На входе имеются данные о положении дел авторынка Казахстана за период с января по сентябрь 2019 года.
Описание полей датасета:
Год – год продажи (2019)Месяц – месяц продажи (январь - сентябрь)Компания – название автоцентраБренд – название продаваемой марки автомобиляМодель – название модели автомобиляМодификация – модификация модели автомобиляГод выпуска – год производства автомобиляСтрана-производитель – страна, где произведен автомобильВид топлива – бензин, дизель, электричество, гибридОбъём двиг л – объем двигателя автомобиля в литрахКоробка передач – тип коробки переключения передачТип привода – в итоге оставляем RWD – задний привод, FWD – передний привод, 4WD – полный привод, 2WD – все остальноеСегмент – сегмент, к которому относится автоРегион – регион продажиНаименование дилерского центра – название центраТип клиента – юридическое или физическое лицоФорма расчета – наличный и безналичный расчетКоличество – количество автомобилей в заказеЦена USD – цена автомобиляПродажа USD – цена заказа (цена авто умноженная на количество и за вычетом скидок если есть)Область – область продажиСегментация 2013 – сегмент автомобиляКласс 2013 – класс автомобиляСегментация Eng – английская сегментацияЛокализация производства – где произведен автомобильПостановленные задачи:
Общий исследовательский анализ данных:
Анализ продаж Mercur Auto:
Выводы и рекомендации на основании общего анализа и анализа Mercur Auto.
#Для работы с данными
import pandas as pd
import numpy as np
import sweetviz as sv
#Для графиков
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
#Снятие ограничений
import warnings
warnings.filterwarnings("ignore")
pd.set_option("display.max_columns", None)
#Для скачивания датасета
from IPython.display import FileLink
#Здесь живут настройки тем графиков
sns.set_style('darkgrid')
plt.style.use('ggplot')
#Эт список цветовых решений для плотли
#print(plt.style.available)
# Чтобы не возникло сложностей с запуском, я добавлю здесь команды для установки библиотек на машину с которой будет запущена тетрадь.
# Прежде всего необходимо открыть терминал (либо выполнить в самой ячейке), и запустить следующие команды:
# Sweet-Viz можно установить этой командой:
# $ pip install sweetviz
# Для установки FileLink:
# !pip install ipyfilechooser
#Функция для вывода информации о датасете
def inform(df):
display(df.head()) # вывод первых 5 строк таблицы
df.info() # получение информации
print()
print ('Количество дубликатов:', df.duplicated().sum())
print()
print ('Число пропусков:\n', df.isna().sum())
print()
print ('Доля пропусков:\n', df.isna().mean()*100,1)
return df
#Переменная с локальным путём к файлу. При запуске с другой машины заменить путь на местный :)
patch = 'C:/Users/79990/Desktop/auto_kz/df/'
#Выгрузка информации о датасете
auto = pd.read_csv(patch + 'auto_kz.csv', sep=';')
auto = inform(auto)
| Год | Месяц | Компания | Бренд | Модель | Модификация | Год выпуска | Страна-производитель | Вид топлива | Объём двиг, л, | Коробка передач | Тип привода | Сегмент | Регион | Наименование дилерского центра | Тип клиента | Форма расчета | Количество | Цена, USD | Продажа, USD | Область | Сегментация 2013 | Класс 2013 | Сегментация Eng | Локализация производства | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2019 | Май | Mercur Auto | Audi | A3 | TFSI | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Легковые автомобили Premium | Алматы | Mercur Auto Алматы | Физ. Лицо | безналичный | 1.0 | 28115 | 28115 | г.Алматы | Легковые автомобили | C класс | C | Импорт |
| 1 | 2019 | Август | Mercur Auto | Audi | A3 | TFSI | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Легковые автомобили Premium | Алматы | Mercur Auto Алматы | Юр. Лицо | наличный | 1.0 | 32246,99 | 32246,99 | г.Алматы | Легковые автомобили | C класс | C | Импорт |
| 2 | 2019 | Апрель | Mercur Auto | Audi | A4 | TFSI | 2018 | Германия | Бензин | 1,4 | S-Tronic | FWD | Легковые автомобили Premium | Алматы | Mercur Auto Алматы | Физ. Лицо | безналичный | 1.0 | 32000 | 32000 | г.Алматы | Легковые автомобили | D класс | D | Импорт |
| 3 | 2019 | Июль | Mercur Auto | Audi | A4 | TFSI | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Легковые автомобили Premium | Алматы | Mercur Auto Алматы | Юр. Лицо | безналичный | 1.0 | 31929 | 31929 | г.Алматы | Легковые автомобили | D класс | D | Импорт |
| 4 | 2019 | Июль | Mercur Auto | Audi | A4 | TFSI | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Легковые автомобили Premium | Алматы | Mercur Auto Алматы | Физ. Лицо | наличный | 1.0 | 31929 | 31929 | г.Алматы | Легковые автомобили | D класс | D | Импорт |
<class 'pandas.core.frame.DataFrame'> RangeIndex: 39966 entries, 0 to 39965 Data columns (total 25 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Год 39966 non-null int64 1 Месяц 39966 non-null object 2 Компания 39966 non-null object 3 Бренд 39966 non-null object 4 Модель 39966 non-null object 5 Модификация 36375 non-null object 6 Год выпуска 39465 non-null object 7 Страна-производитель 39966 non-null object 8 Вид топлива 36826 non-null object 9 Объём двиг, л, 35708 non-null object 10 Коробка передач 36711 non-null object 11 Тип привода 35677 non-null object 12 Сегмент 33205 non-null object 13 Регион 39966 non-null object 14 Наименование дилерского центра 39966 non-null object 15 Тип клиента 32919 non-null object 16 Форма расчета 14038 non-null object 17 Количество 39960 non-null float64 18 Цена, USD 39966 non-null object 19 Продажа, USD 39966 non-null object 20 Область 39966 non-null object 21 Сегментация 2013 39966 non-null object 22 Класс 2013 39966 non-null object 23 Сегментация Eng 39966 non-null object 24 Локализация производства 39966 non-null object dtypes: float64(1), int64(1), object(23) memory usage: 7.6+ MB Количество дубликатов: 18698 Число пропусков: Год 0 Месяц 0 Компания 0 Бренд 0 Модель 0 Модификация 3591 Год выпуска 501 Страна-производитель 0 Вид топлива 3140 Объём двиг, л, 4258 Коробка передач 3255 Тип привода 4289 Сегмент 6761 Регион 0 Наименование дилерского центра 0 Тип клиента 7047 Форма расчета 25928 Количество 6 Цена, USD 0 Продажа, USD 0 Область 0 Сегментация 2013 0 Класс 2013 0 Сегментация Eng 0 Локализация производства 0 dtype: int64 Доля пропусков: Год 0.000000 Месяц 0.000000 Компания 0.000000 Бренд 0.000000 Модель 0.000000 Модификация 8.985137 Год выпуска 1.253566 Страна-производитель 0.000000 Вид топлива 7.856678 Объём двиг, л, 10.654056 Коробка передач 8.144423 Тип привода 10.731622 Сегмент 16.916879 Регион 0.000000 Наименование дилерского центра 0.000000 Тип клиента 17.632488 Форма расчета 64.875144 Количество 0.015013 Цена, USD 0.000000 Продажа, USD 0.000000 Область 0.000000 Сегментация 2013 0.000000 Класс 2013 0.000000 Сегментация Eng 0.000000 Локализация производства 0.000000 dtype: float64 1
#Данный способ развертывает в браузере html дашборд с полной информацией о данных которые мы скармливаем библиотеке sweetviz
#При необходимости открыть дашборд и просмотреть данные - убрать # со строки my_report.show_html()
my_report = sv.analyze(auto)
#my_report.show_html()
Предварительно наблюдаем несоответсвие типов данных, множество дубликатов, достаточно большое количество пропусков. И это только начало :) Согласовав с заказчиком, избавлюсь от полей которые дублируют информацию и будут мешать анализу данных.
Наличие такого большого количества дубликатов (почти половина датасета, 18 698 из 39 966 строк) обосновано тем, что при сборе данных отсутствует уникальная идентификафия строк. Удалять я их пока не стану, т.к. удаление в дальнейшем может исказить анализ этих данных, и к тому же на крайний случай удалить дубли никогда не поздно.
Данные нуждаются в тщательном изучении и устранении всех ошибок, коих здесь весьма не мало.
P.S. Развернув дополнительно дашборд с визуализацией данных мной было замечено внушительное количество неявных дубликатов, с чем буду разбираться по ходу проведения предобработки.
Избавляю датасет от лишнего.
#Удаляю то что дублируется либо не имеет отношения к дальнейшему анализу
auto = auto.drop(columns=['Модификация', 'Сегмент', 'Наименование дилерского центра', 'Форма расчета', 'Сегментация Eng', 'Локализация производства'])
#Переименую столбцы в человеческий вид
auto = auto.rename(columns={'Сегментация 2013': 'Сегментация', 'Класс 2013': 'Класс', 'Объём двиг, л,': 'Объем двигателя', 'Страна-производитель': 'Производитель',
'Продажа, USD': 'Продажа USD', 'Цена, USD': 'Цена USD'})
#Теперь все названия приведу к snake case, с ними будет удобнее работать.
auto.columns = auto.columns.str.lower().str.replace(' ', '_')
#Глянем на преображение
auto.head()
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2019 | Май | Mercur Auto | Audi | A3 | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Алматы | Физ. Лицо | 1.0 | 28115 | 28115 | г.Алматы | Легковые автомобили | C класс |
| 1 | 2019 | Август | Mercur Auto | Audi | A3 | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Алматы | Юр. Лицо | 1.0 | 32246,99 | 32246,99 | г.Алматы | Легковые автомобили | C класс |
| 2 | 2019 | Апрель | Mercur Auto | Audi | A4 | 2018 | Германия | Бензин | 1,4 | S-Tronic | FWD | Алматы | Физ. Лицо | 1.0 | 32000 | 32000 | г.Алматы | Легковые автомобили | D класс |
| 3 | 2019 | Июль | Mercur Auto | Audi | A4 | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Алматы | Юр. Лицо | 1.0 | 31929 | 31929 | г.Алматы | Легковые автомобили | D класс |
| 4 | 2019 | Июль | Mercur Auto | Audi | A4 | 2018 | Германия | Бензин | 1,4 | S-tronic | передний | Алматы | Физ. Лицо | 1.0 | 31929 | 31929 | г.Алматы | Легковые автомобили | D класс |
Датасет очищен от ненужных полей, теперь работать с ним чуть комфортнее. Перейдем к этапу изменения типов данных.
Все столбцы имеющие информацию с целочисленными значениями, и числам с плавающей точкой необходимо привести к другим типам данных (int и float соответственно), для дальнейшей возможности работать с ними. Для начала я выведу уникальные значения каждого столбца по отдельности чтобы понимать какие ошибки закрались при записи, исправлю их, а затем выполню замену типа данных. Таким образом мы сэкономим время увидев сразу какие неявные дубликаты прячутся в массиве данных, и приведем их к рабочему состоянию.
#Вывод уникальных значений столбцов которые нас интересуют
print('Уникальные значения столбца "Количество":', auto['количество'].unique())
print()
print('Уникальные значения столбца "Год выпуска":', auto['год_выпуска'].unique())
print()
print('Уникальные значения столбца "Объем двигателя":', auto['объем_двигателя'].unique())
Уникальные значения столбца "Количество": [ 1. 2. 4. 3. 7. 5. 8. 10. 6. 9. 11. 19. 12. 70. 29. 18. 37. 17. 15. 24. 14. 13. 25. 63. 23. 30. 21. 60. nan 22. 16. 35. 28. 32. 54. 115. 46. 33. 47. 20. 66. 27. 50. 36. 26. 31. 34. 40. 43. 51. 42. 38. 41. 100. -1. 79. 62.] Уникальные значения столбца "Год выпуска": ['2018' '2017' '2019' nan '2016' '2014' '2013' '2011' '2\xa0018' '2\xa0019'] Уникальные значения столбца "Объем двигателя": ['1,4' '2' '3' '4,4' '6,6' '1,5' '1,596' '2,4' '1,7' '26,7' '25,7' '24,7' '23,7' '22,7' '21,7' '20,7' '19,7' '18,7' '17,7' '16,7' '15,7' '14,7' '13,7' '12,7' '11,7' '10,7' '9,7' '8,7' '7,7' '6,7' '5,7' '4,7' '3,7' '2,7' '6,2' '1,4 Turbo' '2,5' '1,6' nan '2,8' '4,3' '4,3,' '1,6 MPI' '2,0 MPI' '2,4 GDI' '2,4 MPI' '2,5 CRDI VGT' '2,5 CRDI WGT' '3,9' '7,5' '12,3' '1,6 T-GDI' '2,0 CRDI' '2.0' '3,5' '5,6' '5,2' '3,0 L' '1.6' '1.5' '5' '1,598' '1,248' '1,998' '2,359' '1,999' '3,342' '1,591' '3,47' '1,69' '1,774' '2.5' '2.7 ' '3.5' '2.7' '4.6' '4,6' '5.7' '1,8' '10,5' '4' '5,5' '12' '12,8' '11' '2,2' '1,2' '1,485' 'MT' 'AT' '0' '13' '1,33' '#Н/Д' '4.0' '2.4G' '2,4G' '2.8' '2,693' '2,0' '3,8' '3.8' '1,2T' '3,6' '7,6' '4,9' '2.0h' '2,9' '400 Л.С.' '4,98 L,' '4,98' '88 KWH' '8,4 L,' '6,7L' '6,5']
Выведя уникальные значения наблюдается следующая картина: В столбце с количеством есть значения NaN и их следует заменить заглушкой 0, потому что в противном случае не получится изменить тип данных. Отрицательное значение -1 полагаю что является возвратом, или же сбой при записи данных. Тоже заменить заглушкой 0. В уникальных значениях года выпуска наблюдаются некорректные записи года, полагаю что это связано с ошибкой при конвертации данных из екселя в .csv, их я верну в нормальный вид, а пропущенные значения NaN я удалю, т.к. их 1.25% во всем датасете, а значит отсутствие их на анализ никак не повлияет.
В столбце с объемом двигателя творится ад! Здесь следует все привести в единому стандарту, заполнить пустые значения (надо подумать чем и как). Я наблюдаю типы двигателя вместо объема (методом поиска в интернете соответсвия объема этим типам можно заполнить значения), значение с лошадинными силами думаю так же можно вывести на экран отдельно и понять к каким авто это относится, а после этого заменить значения на объем двигателя согласно характеристикам в интернете.
Так же есть столбцы с продажей и ценой в долларах, где иногда встречаются запятые вместо точек. Это связано с человеческим фактором при записи данных сотрудниками, форма заполнения допускает и точку и запятую как правильный символ при записи, потому и имеем отсутствие единого стандарта. Исправлю заменой запятых на точки, ведь запятая используется в качестве разделителя тысяч, а это не является стандартным форматом для преобразования в float.
#Поставлю заглушку 0 для пропущенных значений в количестве, изменю тип данных
auto['количество'].fillna(0, inplace=True)
auto['количество'] = auto['количество'].replace(-1, 0)
auto['количество'] = auto['количество'].astype(int)
#Удаление пропусков года выпуска (их менее 1% во всем датасете, ничего не потеряем)
auto.dropna(subset=['год_выпуска'], inplace=True)
auto['год_выпуска'] = auto['год_выпуска'].replace({'2\xa0018': '2018', '2\xa0019': '2019'}) #Ставим адекватный номер года
auto['год_выпуска'] = auto['год_выпуска'].astype(int)
#Меняю запятые появившиеся при корявой записи стоимости на точки (иначе заменить тип данных не получится), и меняю типы данных
auto['продажа_usd'] = auto['продажа_usd'].str.replace(',', '.').astype(float)
auto['цена_usd'] = auto['цена_usd'].str.replace(',', '.').astype(float)
Теперь отдельно разберемся с объемом двигателя...
#Начну с простого. Выведу на экран значения авто у которых указаны лошадинные силы, прогуглю, и заменю на верные
engine = auto[auto['объем_двигателя'] == '400 Л.С.']
engine
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 39544 | 2019 | Февраль | Almaty Motors Premium | Jaguar | I-Pace | 2019 | UK | Электро | 400 Л.С. | РЕДУКТОР | 4WD | Алматы | Физ. Лицо | 1 | 117236.9729 | 117236.9729 | г.Алматы | Внедорожники | Компактные SUV |
| 39545 | 2019 | Апрель | Almaty Motors Premium | Jaguar | I-Pace | 2019 | UK | Электро | 400 Л.С. | РЕДУКТОР | 4WD | Алматы | Физ. Лицо | 1 | 105388.7924 | 105388.7924 | г.Алматы | Внедорожники | Компактные SUV |
| 39546 | 2019 | Июнь | Almaty Motors Premium | Jaguar | I-Pace | 2019 | UK | Электро | 400 Л.С. | РЕДУКТОР | 4WD | Алматы | Юр. Лицо | 1 | 120413.2793 | 120413.2793 | г.Алматы | Внедорожники | Компактные SUV |
По скольку все три электромобили - классифицировать объем двигателя в литрах будет не корректно. Потому проставлю значение 0 для Ягуаров.
Теперь разберем что значат буквенные обозначения попавшие в объем двигателя. Путем сёрфинга информации в интернете вот что мне удалось найти:
МТ и АТ - механическая и автоматическая трансмиссия, это съехавшие значения (вероятно при выгрузке данных с БД), которые необходимо переместить в столбец коробки передач.88 KWH - обозначение относящееся к электрокару. Так же как и с предыдущими - не корректно указывать объем, а потому следует заменить эти значения на 0.#Н/Д - обозначение отсутсвия данных. Возможно это связано с ошибкой при выгрузке данных с базы, а может быть это связано с человеческим фактором. Выведя на экран информацию с таким заполнением можно будет найти в интернете характеристики и заполнить их вручную.Что касается остальных значений - оставим один символ после запятой, тем самым приведем значения к единому стандарту и удалим лишние подписи которые нас не интересуют, и не будут играть роли при анализе.
#Перемещение съехавших значений на свое место.
#Создаем датасет без сдвинутых ячеек
unchanged = auto.query("объем_двигателя not in ['MT', 'AT']")
# датасет со сдвинутыми значениями
to_change = auto.query("объем_двигателя in ['MT', 'AT']")
# чистим датасет от сдвига ячеек
to_change['тип_привода'] = to_change['объем_двигателя']
to_change['объем_двигателя'] = to_change['вид_топлива']
to_change['вид_топлива'] = np.NaN
# сливаем датасеты обратно
auto = pd.concat([to_change, unchanged])
# проверяем корректность слияния
auto.shape
(39465, 19)
#Точно так же выводим на экран информацию авто с указанием буквенных обозначений/отсутствующих в поле объема двигаетля
engine = auto[(auto['объем_двигателя'] == '#Н/Д') | (auto['объем_двигателя'] == '88 KWH')]
engine
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 31148 | 2019 | Февраль | Toyota Motor Kazakhstan | Toyota | Corolla | 2019 | Турция | Бензин | #Н/Д | #Н/Д | #Н/Д | Нур-Султан | Физ. Лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс |
| 31149 | 2019 | Февраль | Toyota Motor Kazakhstan | Toyota | Corolla | 2019 | Турция | Бензин | #Н/Д | #Н/Д | #Н/Д | Нур-Султан | Физ. Лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс |
| 32670 | 2019 | Апрель | Toyota Motor Kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Бензин | #Н/Д | #Н/Д | #Н/Д | Алматы | Юр. Лицо | 1 | 30870.28194 | 30870.28194 | г.Алматы | Пикапы | Pick-ups |
| 33070 | 2019 | Июль | Toyota Motor Kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Бензин | #Н/Д | #Н/Д | #Н/Д | Атырау | Физ. Лицо | 1 | 27012.45730 | 27012.45730 | Атырауская область | Пикапы | Pick-ups |
| 39818 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39819 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39820 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39821 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39822 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39823 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39824 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39825 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39826 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
| 39827 | 2019 | Июль | Allur Auto | ANKAI | HFF6124G03EV3 | 2019 | Республика Казахстан | Электричество | 88 KWH | NaN | 2WD | Костанай | Юр. Лицо | 1 | 307986.36330 | 307986.36330 | Костанайская область | Коммерческие автомобили | Большие автобусы |
Выведя информацию с марками авто где отсутствуют объема двигателя, наблюдаем картину того что данных нет так же и в столбцах с коробкой передач и типом привода. Ситуация исправимая, вручную укажем нужные параметры взяв их с интернета. Так же в таблицу попалось множество дублей одной модели электро автобуса ANKAI, у которого помимо некорректно указанного объема двигателя еще отсутствует тип коробки передач. Опять же, исправимо внесением данных вручную.
P.S. Полазив на авто.ру, я увидел что короллы 19го года (относящиеся к 12 поколению) имеют несколько вариаций исполнения. Укажу значечния которые чаще встречаются на рынке, а именно: передний привод, механическая кп, и средний объем двигателя - 1.6 литра. Для электро автобуса кпп автомат, объем двигателя меняем на ноль. Для HILUX DC объем 2.8, автомат, 4WD.
#Пропущенные значения для короллы и анкая
#Пропуски для бренда Toyota и моделей Corolla и HILUX DC
toyota_corolla = (auto['бренд'] == 'Toyota') & (auto['модель'] == 'Corolla')
auto.loc[toyota_corolla, ['объем_двигателя', 'коробка_передач', 'тип_привода']] = auto.loc[toyota_corolla, ['объем_двигателя', 'коробка_передач', 'тип_привода']
].fillna(value={'объем_двигателя': 1.6, 'коробка_передач': 'МТ', 'тип_привода': 'FWD'})
toyota_hilux = (auto['бренд'] == 'Toyota') & (auto['модель'] == 'HILUX DC')
auto.loc[toyota_hilux, ['объем_двигателя', 'коробка_передач', 'тип_привода']] = auto.loc[toyota_hilux, ['объем_двигателя', 'коробка_передач', 'тип_привода']
].fillna(value={'объем_двигателя': 2.8, 'коробка_передач': 'АТ', 'тип_привода': '4WD'})
#Пропуски для бренда ANKAI
ankai = (auto['бренд'] == 'ANKAI') & (auto['модель'] == 'HFF6124G03EV3')
auto.loc[ankai, ['объем_двигателя', 'коробка_передач']] = auto.loc[ankai, ['объем_двигателя', 'коробка_передач']
].fillna(value={'объем_двигателя': 0, 'коробка_передач': 'АТ'})
#Проверка связи
auto['объем_двигателя'].unique()
array(['2', '1,6', '1,4', '3', '4,4', '6,6', '1,5', '1,596', '2,4', '1,7',
'26,7', '25,7', '24,7', '23,7', '22,7', '21,7', '20,7', '19,7',
'18,7', '17,7', '16,7', '15,7', '14,7', '13,7', '12,7', '11,7',
'10,7', '9,7', '8,7', '7,7', '6,7', '5,7', '4,7', '3,7', '2,7',
'6,2', '1,4 Turbo', '2,5', nan, '2,8', '4,3', '4,3,', '1,6 MPI',
'2,0 MPI', '2,4 GDI', '2,4 MPI', '2,5 CRDI VGT', '2,5 CRDI WGT',
'3,9', '7,5', '12,3', '1,6 T-GDI', '2,0 CRDI', '2.0', '3,5', '5,6',
'5,2', '3,0 L', '1.6', '1.5', '5', '1,598', '1,248', '1,998',
'2,359', '1,999', '3,342', '1,591', '3,47', '1,69', '1,774', '2.5',
'2.7 ', '3.5', '2.7', '4.6', '4,6', '5.7', '1,8', '10,5', '4',
'5,5', '12', '12,8', '11', '2,2', '1,2', '1,485', '0', '13',
'1,33', '#Н/Д', '4.0', '2.4G', '2,4G', '2.8', '2,693', '2,0',
'3,8', '3.8', '1,2T', '3,6', '7,6', '4,9', '2.0h', '2,9',
'400 Л.С.', '4,98 L,', '4,98', '88 KWH', '8,4 L,', '6,7L', '6,5'],
dtype=object)
#функция для удаления лишних символов из объема двигателя
def engine_cleaner(cell):
if isinstance(cell, int):
cell = str(cell)
good_symbols = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'] # список символов, которые мы оставляем
new_cell = '' # новая пустая строка куда мы будем добавлять "хорошие" символы
for element in cell:
if element in good_symbols:
new_cell += element
if new_cell.endswith('.'): # отдельно обработаем момент где в конце остается точка
new_cell = new_cell[:-1]
return new_cell
#Для корректной работы функции приведем столбец к типу строка
auto['объем_двигателя'] = auto['объем_двигателя'].astype('str')
#Как и в предыдущем случае, меняем запятые на точки
auto['объем_двигателя'] = auto['объем_двигателя'].str.replace(',', '.')
#Замена значения электрокаров на ноль
auto['объем_двигателя'] = auto['объем_двигателя'].replace('400 Л.С.', 0)
auto['объем_двигателя'] = auto['объем_двигателя'].replace('88 KWH', 0)
#Применяем функцию
auto['объем_двигателя'] = auto['объем_двигателя'].apply(engine_cleaner)
#Проверка связи
auto['объем_двигателя'].unique()
array(['2', '1.6', '1.4', '3', '4.4', '6.6', '1.5', '1.596', '2.4', '1.7',
'26.7', '25.7', '24.7', '23.7', '22.7', '21.7', '20.7', '19.7',
'18.7', '17.7', '16.7', '15.7', '14.7', '13.7', '12.7', '11.7',
'10.7', '9.7', '8.7', '7.7', '6.7', '5.7', '4.7', '3.7', '2.7',
'6.2', '2.5', '', '2.8', '4.3', '2.0', '3.9', '7.5', '12.3', '3.5',
'5.6', '5.2', '3.0', '5', '1.598', '1.248', '1.998', '2.359',
'1.999', '3.342', '1.591', '3.47', '1.69', '1.774', '4.6', '1.8',
'10.5', '4', '5.5', '12', '12.8', '11', '2.2', '1.2', '1.485', '0',
'13', '1.33', '4.0', '2.693', '3.8', '3.6', '7.6', '4.9', '2.9',
'4.98', '8.4', '6.5'], dtype=object)
auto.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 39465 entries, 23723 to 39965 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 год 39465 non-null int64 1 месяц 39465 non-null object 2 компания 39465 non-null object 3 бренд 39465 non-null object 4 модель 39465 non-null object 5 год_выпуска 39465 non-null int32 6 производитель 39465 non-null object 7 вид_топлива 36710 non-null object 8 объем_двигателя 39465 non-null object 9 коробка_передач 36453 non-null object 10 тип_привода 35605 non-null object 11 регион 39465 non-null object 12 тип_клиента 32829 non-null object 13 количество 39465 non-null int32 14 цена_usd 39465 non-null float64 15 продажа_usd 39465 non-null float64 16 область 39465 non-null object 17 сегментация 39465 non-null object 18 класс 39465 non-null object dtypes: float64(2), int32(2), int64(1), object(14) memory usage: 5.7+ MB
Столбцы приведены к нужным типам данных, удалены лишние символы, исправлены ошибки возникшие при записи/конвертации данных, неверные значения заменены на правильные.
Теперь, когда числа приведены в порядок, самое время поработать с остальными столбцами. Прежде всего выведу уникальные значения для остальных, и уже будет понятно что с этим делать дальше.
#Функция, которой передается датафрейм и столбцы для вывода уникальных значений.
#Не придется писать лапками код.
def values(dataframe, columns, values_per_line=15): #values_per_line ограничивает строку на 15 значений (чтобы не устали глаза листать)
for column in columns:
unique_values = dataframe[column].unique() #Здесь собираются уникальные значения столбца
print(f"\033[1mУникальные значения столбца '{column}':\033[0m") # escape-код ANSI, f строка выделяется жирным шрифтом.
for i in range(0, len(unique_values), values_per_line): #Цикл переносящий значения на новую строку, если хи число превышает 15
values_subset = unique_values[i:i+values_per_line]
print(', '.join(map(str, values_subset)))
print() #Пустая строка между выводами, для комфортного отображения информации
#Вывод значений
values(auto, ['месяц', 'компания', 'бренд', 'модель', 'производитель', 'вид_топлива', 'коробка_передач',
'тип_привода', 'регион', 'тип_клиента', 'область', 'сегментация', 'класс']
)
Уникальные значения столбца 'месяц': Январь, Май, Август, Апрель, Июль, Февраль, Июнь, Сентябрь, Март Уникальные значения столбца 'компания': Renault Россия, Mercur Auto, Автоцентр-Бавария, БИПЭК АВТО, Вираж, Eurasia Motor Premium, Daewoo Bus Kazakhstan, Caspian Motors, Каспиан Моторс, СемАЗ, Astana Motors, Astana Motors , Hyundai Com Trans Kazakhstan , Nissan Manufacturing RUS, СВС-ТРАНС Allur Auto, Almaty Motors Premium, TERRA MOTORS, ТК КАМАЗ, Toyota Motor Kazakhstan, Лифан Моторс Рус, MAN Truck & Bus Kazakhstan, Автомир ГК, Autokapital, Автокапитал, ММС Рус, MMC RUS, Mercur Autos, УзАвто-Казахстан, Равон Моторс Казахстан Ravon Motors Kazakstan, Scania Central Asia, Subaru Kazakhstan, Volkswagen Group Rus, Автодом Motors KST, Автомир-Центр, ТОО "Eurasia Motor Zhaik", Scandinavian Motors, Хино Моторс Казахстан, Hino Motors Уникальные значения столбца 'бренд': Renault, Audi, BMW, Chevrolet, Daewoo, Ford, Foton, GAZ, Hyundai, Hyundai Truck & Bus, Infiniti, Isuzu, Iveco, Jac, Jaguar KAMAZ, Kia, Lada, Land Rover, Lexus, Lifan, MAN, Mazda, Mercedes-Benz, Mercedes-Benz Trucks, Mini, Mitsubishi, Nissan, Peugeot, Porsche Ravon, Scania, Skoda, Subaru, Toyota, UAZ, Volkswagen, Volvo, Урал, Cadillac, Shacman, Hino, Dong Feng, ANKAI, Nefaz Yutong Уникальные значения столбца 'модель': Duster, Sandero, A3, A4, A6, A7, A8, Q5, Q7, 3 серия, 5 серия, 6 серия, 7 серия, X1, X3 X4, X5, X6, X7, Z4, Aveo, Captiva, Niva, Tahoe, Tracker, BS 106 A, Fiesta, Mondeo, BJ3253DMPKB-AD, 2217 2310, 2705, 2752, 3221, 3302, 3308, 3309, Next, Accent, Creta, Elantra, Santa Fe, Sonata, TQ-1/H-1, County H350, HD 170, HD 65, HD 78, Universe, Tucson, Q50, QX50, QX60, QX80, D-MAX, NMR, NPR, Daily, Daily A Daily V, Stralis, Tipper, S3, S5, F-Pace, F-Type, XE, XF, XJ, 4308, 4311, 43118, 43253, 43502 44108, 45142, 45143, 53215, 53504, 53605, 54115, 5490, 65111, 65115, 65116, 65117, 6520, 65206, 65225 66052, 6606, Cerato, Optima, Picanto, Quoris, Rio, Sorento, Soul, Sportage, 4x4, Granta, Kalina, Largus, Vesta XRAY, ВИС, Discovery, Discovery Sport, Range Rover, Range Rover Evoque, Range Rover Sport, ES, GX, LS, LX, NX, RX, RXH, Murman Solano, X50, X60, TG, 6, CX-5, A-Class, C-Class, CLA-Class, CLS-Class, E-Class, G-Class, GLA-Class, GLC-Class, GLE-Class GLS-Class, S-Class, Actros, Sprinter, Tourismo, V-Class, Vito, Countryman, ASX, Outlander, Pajero IV, Pajero Sport, Almera, Juke, Murano Qashqai, Terrano, X-Trail, 301, Partner Panel Van, 911 Carrera S, Cayenne, Macan, Panamera, Nexia R3, R4, Kaptur, Koleos, Logan, Master G-Series, P-Series, R-Series, Octavia, Rapid, Superb, Forester, Legacy, Outback, XV, Camry, Corolla, HIGHLANDER, HILUX DC, LC Prado LC200, RAV4, 2206, 3151, 3303, 3741, 3909, 3962, Cargo, Patriot, Patriot Pickup, Amarok, Caddy Kasten , Caddy Maxi Kombi, Caravelle Jetta, Multivan, Polo, Tiguan, Touareg, Transporter, Transporter Kasten, XC90, 4320, 4320-1951-40, 4320-1951-60, 5557, MYWAY, CX-9, HD 35 Range Rover Velar, BS 106 D, Kodiaq, Escalade, GLC Coupe, X200, E-PACE, Dokker, Eclipse Cross, X70, N120, N75, T6, SX3258DR384, iev S-Series, NQR, X2, S90, XC60, C-HR, 300, XC40, N56, XT5, 500, Stinger, Hatch, Traverse, NMS85 BJ1069VDJEA-F1, HD 79, BWC6665GA5, i8, UX, 8 серия, Cabrio, HF-D105, NPS, Q8, RS5, Teramont, 5299, I-Pace, S7 45141, 32551, BC 211 MA, EX8, BC 095, Camaro, HFF6850G, Transporter Kombi , GLE Coupe, HFF6124G03EV3, HFF6127GZ-4, Setra, ZK6108HGH, Arkana, V90 58815Z Уникальные значения столбца 'производитель': Российская Федерация, Германия, США, Австрия, Республика Казахстан, Корея, Япония, Таиланд, Китай, UK, Узбекистан, Венгрия, Турция, Испания, Нидерланды Польша, Швеция, Белоруссия, Бельгия Уникальные значения столбца 'вид_топлива': nan, Бензин, Дизель, дизель , бензин , гибрид, 1,6, 0, Электро, Электричество Уникальные значения столбца 'коробка_передач': 4WD, Передний, S-tronic, S-Tronic, Tiptronic, АКПП, АКП, Steptronic, AT, 6 АТ, 5 МТ, 6АТ, MT, 8AT, 5МТ Powershift S6, 6AT, nan, Мех., 6 AT, 6 MT, 6MT, 5 AT, 5AT, МКПП, 7 DCT, 7DCT, 8 AT, МТ, CVT DCT, 4 АТ, 6 МТ, 6МТ, 4АТ, 4AT, 8АТ, 8 АТ, 5MT, AMT, CVT (вариатор), CVT (вариATор), CVT(вAриATор), 7G-TRONIC, 9G-TRONIC 12AT, 12АТ, 5АТ, 7АТ, 7AT, 6M/T, PDK, 8-ступ АКПП, 8, 8АКПП, 8 АКПП Tiptronic S, 7 АКПП (PDK), 7 АКПП PDK, 8 АКПП (PDK), АТ АT, МT, 0, 7 DSG, 7DSG, 6 DSG, 6DSG, #Н/Д, DSG, 6A, 6А, 5M, A/T, M/T, МКП 5М, М/T, 7 АКП, 7АКП, А/T, 8A, TDI, 9AT, РЕДУКТОР Уникальные значения столбца 'тип_привода': MT, AT, передний, FWD, quattro, Задний, Полный, AWD, Передний, 4WD, 4х2.2, nan, RWD, 2 WD, 2WD 4 WD, 4X4, 4х4, 4x4, 4x2, 4х2, 4X2, Астана, Передний (FF), 0, FF, #Н/Д, полный, 4Motion Уникальные значения столбца 'регион': Уральск, Нур-Султан, Кызылорда, Караганда, Усть-Каменогорск, Шымкент, Алматы, Костанай, Петропавловск, Павлодар, Семей, Актау, Атырау, Актобе, Кокшетау Рудный, Тараз, Туркестан, Талдыкорган, ЭКСПОРТ, Кульсары, Каскелен, Экибастуз, Риддер, Сарыагаш, Зыряновск Уникальные значения столбца 'тип_клиента': nan, Физ. Лицо, Юр. Лицо, Юр.Лицо, физ.лицо, юридическое, физическое, ФизЛицо, ЮрЛицо, Корп. клиент Уникальные значения столбца 'область': Западно-Казахстанская область, г.Нур-Султан, Кызылординская область, Карагандинская область, Восточно-Казахстанская область, Южно-Казахстанская область, г.Алматы, Костанайская область, Северо-Казахстанская область, Павлодарская область, Мангистауская область, Атырауская область, Актюбинская область, Акмолинская область, Жамбылская область Туркестанская область, Алматинская область, Экспорт область Уникальные значения столбца 'сегментация': Внедорожники, Легковые автомобили, Коммерческие автомобили, Минивэны, Пикапы Уникальные значения столбца 'класс': Субкомпактные SUV, B класс, C класс, D класс, E класс, F класс, Среднеразмерные SUV, Полноразмерные SUV, Спортивные автомобили, Компактные SUV, Большие автобусы, Крупнотоннажные грузовики, Микроавтобусы, Малотоннажные грузовики, Среднетоннажные грузовики Полноразмерный Минивэн, Средние автобусы, Pick-ups, Развозные автомобили, A класс, Компактвэн
После изучения значений в остальных столбцах можно отметить следующие моменты:
'компания'- Видно что присутствуют неявные дубли, некоторые компании повторяются на русской и английской раскладке. Объединить названия исключив путаницу.
'модель'- Ну.... По скольку здесь большое множество моделей и бегло осматривая их я не могу разглядеть неявные дубли (если они конечно тут есть), допущу вариант того что это адекватные названия/номера моделей которые имеются в серии выпуска авто разных производителей. Пока ничего делать с этим столбцом не буду, на первый взгляд все нормально.
'производитель'- Все названия стран выглядят адекватно, кроме UK. Заменить на Англию.
'вид_топлива'- Вижу пропуски, посмотрим что это (возможно сказались съехавшие значения), закрались значения объема двигателя - следует переместить на место, для оптимизации веса датасета и скорости его обработки машиной предлагаю сделать буквенные обозначения вместо подписей:
Э - ЭлектричествоБ - БензинГ - ГибридД - Дизель'коробка_передач'- Полный фарш. Никакой стандартизации ввода данных, с этим придется поработать разделив значения на автомат (АТ), механику(МТ) и роботов (RT). В нашем случае точность в типе коробки передач никак не скажется на качестве анализа этих данных.
'тип_привода'- Снова съехавшие значения механики и автомата со столбца коробки передач. Вернуть на место. Опять же, с целью оптимизации предлагаю все типы привода оформить следующим образом:
RWD - Задний приводFWD - Передний привод4WD - Полный приводAWD - Автоматически подключаемый полный привод'тип_клиента'- Пропуски заполнить на физ лицо если автомобилей куплено не больше двух. Юр лица приобретают как правило больше трех авто. Значения привести к единой форме.
'класс'- Смущает только Pick-ups. Переименовать на Пикап.
Что касаемо не перечисленных столбцов (месяц, бренд, регион, область, сегментация) - при беглом осмотре с ними все в порядке. Приступаем к исправлению грехов в датасете!
#Переименовываю английские значения в столбцах производитель и класс
auto['производитель'] = auto['производитель'].replace({'UK': 'Англия'})
auto['класс'] = auto['класс'].replace({'Pick-ups': 'Пикап'})
#Исправление неявных дублей в столбце компания.
#Приведем все значения к нижнему регистру и уберем лишние пробелы
auto['компания'] = auto['компания'].str.lower().str.strip()
#Вывод значений
auto['компания'].unique()
array(['renault россия', 'mercur auto', 'автоцентр-бавария', 'бипэк авто',
'вираж', 'eurasia motor premium', 'daewoo bus kazakhstan',
'caspian motors', 'каспиан моторс', 'семаз', 'astana motors',
'hyundai com trans kazakhstan', 'nissan manufacturing rus',
'свс-транс', 'allur auto', 'almaty motors premium', 'terra motors',
'тк камаз', 'toyota motor kazakhstan', 'лифан моторс рус',
'man truck & bus kazakhstan', 'автомир гк', 'autokapital',
'автокапитал', 'ммс рус', 'mmc rus', 'mercur autos',
'узавто-казахстан', 'равон моторс казахстан',
'ravon motors kazakstan', 'scania central asia',
'subaru kazakhstan', 'volkswagen group rus', 'автодом motors kst',
'автомир-центр', 'тоо "eurasia motor zhaik"',
'scandinavian motors', 'хино моторс казахстан', 'hino motors'],
dtype=object)
#Теперь одинаковые названия на разных языках
auto['компания'] = auto['компания'].replace({'каспиан моторс': 'caspian motors', 'равон моторс казахстан': 'ravon motors kazakstan',
'хино моторс казахстан': 'hino motors', 'ммс рус': 'mmc rus', 'mercur autos': 'mercur auto',
'автокапитал': 'autokapital'})
auto['компания'].unique()
array(['renault россия', 'mercur auto', 'автоцентр-бавария', 'бипэк авто',
'вираж', 'eurasia motor premium', 'daewoo bus kazakhstan',
'caspian motors', 'семаз', 'astana motors',
'hyundai com trans kazakhstan', 'nissan manufacturing rus',
'свс-транс', 'allur auto', 'almaty motors premium', 'terra motors',
'тк камаз', 'toyota motor kazakhstan', 'лифан моторс рус',
'man truck & bus kazakhstan', 'автомир гк', 'autokapital',
'mmc rus', 'узавто-казахстан', 'ravon motors kazakstan',
'scania central asia', 'subaru kazakhstan', 'volkswagen group rus',
'автодом motors kst', 'автомир-центр', 'тоо "eurasia motor zhaik"',
'scandinavian motors', 'hino motors'], dtype=object)
Ну теперь вроде красота :) производитель, класс и компания исправлены.
#Теперь разберемся с типом клиента
#Приведем все значения к нижнему регистру и уберем лишние пробелы
auto['тип_клиента'] = auto['тип_клиента'].str.lower().str.strip()
auto['тип_клиента'].unique()
array([nan, 'физ. лицо', 'юр. лицо', 'юр.лицо', 'физ.лицо', 'юридическое',
'физическое', 'физлицо', 'юрлицо', 'корп. клиент'], dtype=object)
#Убираем лишнее
auto['тип_клиента'] = auto['тип_клиента'].replace({'юр.лицо': 'юр. лицо', 'физ.лицо': 'физ. лицо', 'юридическое': 'юр. лицо', 'физическое': 'физ. лицо',
'физлицо': 'физ. лицо', 'юрлицо': 'юр. лицо'})
auto['тип_клиента'].unique()
array([nan, 'физ. лицо', 'юр. лицо', 'корп. клиент'], dtype=object)
Несколько слов о отличии юр. лица от корпоративного клиента.
Юридическое лицо - это организация, которая имеет право на совершение действий в соответствии с законодательством, включая заключение контрактов, приобретение и продажу имущества, и так далее.
Корпоративный клиент - это термин, который обычно используется для обозначения клиента, который является юридическим лицом (как крупным, так и мелким предприятием), и который приобретает продукцию или услуги компании. Однако, корпоративный клиент не обязательно должен быть юридическим лицом. Например, в некоторых случаях, крупные индивидуальные клиенты могут быть классифицированы как корпоративные клиенты.
Таким образом, хотя все корпоративные клиенты могут быть юридическими лицами, не все юридические лица являются корпоративными клиентами. Кроме того, некоторые корпоративные клиенты могут быть индивидуальными клиентами.
#Узнаем сколько значений не имеет указанного типа клиента.
print('Количество пропусков в столбце тип клиента:', auto['тип_клиента'].isna().sum())
Количество пропусков в столбце тип клиента: 6636
Согласовав этот момент с заказчиком, решили заполнить пропуски значениями физ или юр лица в следующих случаях: если совершена одна или две покупки - указываем физическое лицо. Все что больше двух является юридическими, т.к. это чаще всего закупка коммерческих предприятий.
#Функция заполняющая пропуски.
def client_type(row):
if pd.isna(row['тип_клиента']):
if row['количество'] >= 2:
return 'физ. лицо'
else:
return 'юр. лицо'
else:
return row['тип_клиента']
#Применение функции
auto['тип_клиента'] = auto.apply(client_type, axis=1)
#Проверка
print('Количество пропусков в столбце тип клиента:', auto['тип_клиента'].isna().sum())
auto['тип_клиента'].unique()
Количество пропусков в столбце тип клиента: 0
array(['юр. лицо', 'физ. лицо', 'корп. клиент'], dtype=object)
Все хорошо, пропуски заполнены, корпоративные клиенты остались на месте, идем дальше.
#Заменим запянутю, т.к. объем двигателя у нас уже отформатирован
auto['вид_топлива'] = auto['вид_топлива'].str.replace(',', '.')
#Найдем строки, где 'тип_топлива' содержит значения '1.6' и '0'
wrong_values = auto[(auto['вид_топлива'] == '1.6') | (auto['вид_топлива'] == '0')]
#Заменим их в столбце 'объем_двигателя'
auto.loc[wrong_values.index, 'объем_двигателя'] = wrong_values['вид_топлива']
#Заменим их в столбце 'тип_топлива' на NaN
auto.loc[wrong_values.index, 'вид_топлива'] = np.nan
#Проверим что получилось
auto['вид_топлива'].unique()
array([nan, 'Бензин', 'Дизель', 'дизель ', 'бензин ', 'гибрид', 'Электро',
'Электричество'], dtype=object)
#Функция для замены значений
def map_fuel_type(value):
if isinstance(value, str): #Проверяем, является ли значение строкой
value = value.strip().lower() #Убираем пробелы и приводим к нижнему регистру
if value == 'бензин':
return 'Б'
elif value == 'дизель' or value == 'дизель ':
return 'Д'
elif value == 'электричество' or value == 'электро':
return 'Э'
elif value == 'гибрид':
return 'Г'
return value #Возвращаем исходное значение, если не нашли соответствие или если значение не является строкой
#Применим, помянем
auto['вид_топлива'] = auto['вид_топлива'].apply(map_fuel_type)
#Проверим что получилось
auto['вид_топлива'].unique()
array([nan, 'Б', 'Д', 'Г', 'Э'], dtype=object)
#Датасет, где только строки с пропущенным значением
not_fuel = auto[auto['вид_топлива'].isna()]
print('Количество пропущенных зачений:', auto['вид_топлива'].isna().sum())
Количество пропущенных зачений: 2761
Предлагаю вывести уникальные значения бренда и модели каждого авто, и заполнить пропущенные значения типом топлива характерым для этих авто согласно информации в интернете. Это даст нам относительно точные данные которыми можно заполнить пропуски коих не мало.
#Группировка по бренду и объединение строк с уникальными моделями
brand_model = not_fuel.groupby('бренд')['модель'].unique().reset_index()
#Преобразование списков моделей в строки
brand_model['модель'] = brand_model['модель'].apply(lambda x: ', '.join(x))
brand_model
| бренд | модель | |
|---|---|---|
| 0 | ANKAI | HF-D105, HFF6850G |
| 1 | Dong Feng | BWC6665GA5 |
| 2 | Foton | BJ3253DMPKB-AD, BJ1069VDJEA-F1 |
| 3 | GAZ | 2310, 2705, 2752, 3221, 3302, 3308, Next |
| 4 | Hyundai Truck & Bus | HD 65, HD 78, Universe, HD 35, EX8 |
| 5 | Iveco | Daily, Daily A, Daily V, Stralis, Tipper |
| 6 | Jac | S3, S5, N120, N75, T6, N56 |
| 7 | Jaguar | I-Pace |
| 8 | Lada | ВИС |
| 9 | MAN | TG |
| 10 | Mazda | 6, CX-5, CX-9 |
| 11 | Peugeot | 301, Partner Panel Van |
| 12 | Renault | Duster, Sandero, Kaptur, Koleos, Logan, Master... |
| 13 | Shacman | SX3258DR384 |
| 14 | UAZ | 3151, 3741, Cargo, Patriot Pickup |
| 15 | Урал | 4320, 4320-1951-40, 4320-1951-60, 5557, 32551 |
На выходе имеем не так много моделей авто в которых есть пробелы данных, а значит вполне реально их заполнить самостоятельно поискав информацию в интернете. Чем я и займусь.
#Ну что ж... Создам словарь с соответствиями моделей и типов топлива
fuel_type = {'HF-D105': 'Б', 'HFF6850G': 'Б', 'BWC6665GA5': 'Б', 'BJ3253DMPKB-AD': 'Б', 'BJ1069VDJEA-F1': 'Б', '2310': 'Б', '2705': 'Б', '2752': 'Б', '3221': 'Б',
'3302': 'Б', '3308': 'Б', 'Next': 'Б', 'HD 65': 'Д', 'HD 78': 'Д', 'Universe': 'Д', 'HD 35': 'Д', 'EX8': 'Д', 'Daily': 'Д', 'Daily A': 'Д', 'Daily V': 'Д',
'Stralis': 'Д', 'Tipper': 'Д', 'S3': 'Б', 'S5': 'Б', 'N120': 'Б', 'N75': 'Б', 'T6': 'Б', 'N56': 'Б', 'I-Pace': 'Э', 'ВИС': 'Б', 'TG': 'Д', '6': 'Б', 'CX-5': 'Б',
'CX-9': 'Б', '301': 'Б', 'Partner Panel Van': 'Б', 'Duster': 'Б', 'Sandero': 'Б', 'Kaptur': 'Б', 'Koleos': 'Б', 'Logan': 'Б', 'Master': 'Д', 'Dokker': 'Б',
'Arkana': 'Б', 'SX3258DR384': 'Д', '3151': 'Б', '3741': 'Б', 'Cargo': 'Б', 'Patriot Pickup': 'Б', '4320': 'Д', '4320-1951-40': 'Д', '4320-1951-60': 'Д',
'5557': 'Д', '32551': 'Д'
}
#Обновляем столбец "вид_топлива" в датасете auto с использованием словаря
auto['вид_топлива'] = auto['вид_топлива'].fillna(auto['модель'].map(fuel_type))
#Проверка что из этого получилось
auto['вид_топлива'].unique()
array(['Б', 'Д', 'Г', 'Э'], dtype=object)
Это успешный успех! Все получилось как и задумывалось, идем дальше.
#Разбираемся с коробкой передач!
#Съехавшее значение "передний" необходимо вернуть на место.
def type_inplace(df):
condition = df['коробка_передач'] == 'Передний' #Условие для выбора значений 'передний' в столбце 'коробка_передач'
df.loc[condition, 'тип_привода'] = 'передний' #Перемещение значения 'передний' из 'коробка_передач' в 'тип_привода'
df.loc[condition, 'коробка_передач'] = np.nan #Замена на NaN
#Применяем
type_inplace(auto)
#Проверка
auto['коробка_передач'].unique()
array(['4WD', nan, 'S-tronic', 'S-Tronic', 'Tiptronic', 'АКПП', 'АКП',
'Steptronic', 'AT', '6 АТ', '5 МТ', '6АТ', 'MT', '8AT', '5МТ',
'Powershift S6', '6AT', 'Мех.', '6 AT', '6 MT', '6MT', '5 AT',
'5AT', 'МКПП', '7 DCT', '7DCT', '8 AT', 'МТ', 'CVT', 'DCT', '4 АТ',
'6 МТ', '6МТ', '4АТ', '4AT', '8АТ', '8 АТ', '5MT', 'AMT',
'CVT (вариатор)', 'CVT (вариATор)', 'CVT(вAриATор)', '7G-TRONIC',
'9G-TRONIC', '12AT', '12АТ', '5АТ', '7АТ', '7AT', '6M/T', 'PDK',
'8-ступ АКПП', '8', '8АКПП', '8 АКПП Tiptronic S', '7 АКПП (PDK)',
'7 АКПП PDK', '8 АКПП (PDK)', 'АТ', 'АT', 'МT', '0', '7 DSG',
'7DSG', '6 DSG', '6DSG', '#Н/Д', 'DSG', '6A', '6А', '5M', 'A/T',
'M/T', 'МКП', '5М', 'М/T', ' 7 АКП', '7АКП', 'А/T', '8A', 'TDI',
'9AT', 'РЕДУКТОР'], dtype=object)
# Создаем словарь для замены значений
transmission_type = {'4WD': 'AT', 'Передний': 'MT', 'S-tronic': 'RT', 'S-Tronic': 'RT', 'Tiptronic': 'RT', 'АКПП': 'AT', 'АКП': 'AT', 'Steptronic': 'RT',
'AT': 'AT', '6 АТ': 'AT', '5 МТ': 'MT', '6АТ': 'AT', 'MT': 'MT', '8AT': 'AT', '5МТ': 'MT', 'Powershift S6': 'RT', '6AT': 'AT',
'Мех.': 'MT', '6 AT': 'AT', '6 MT': 'MT', '6MT': 'MT', '5 AT': 'AT', '5AT': 'AT', 'МКПП': 'MT', '7 DCT': 'RT', '7DCT': 'RT',
'8 AT': 'AT', 'МТ': 'MT', 'CVT': 'RT', 'DCT': 'RT', '4 АТ': 'AT', '6 МТ': 'MT', '6МТ': 'MT', '4АТ': 'AT', '4AT': 'AT', '8АТ': 'AT',
'8 АТ': 'AT', '5MT': 'MT', 'AMT': 'RT', 'CVT (вариатор)': 'RT', 'CVT (вариATор)': 'RT', 'CVT(вAриATор)': 'RT', '7G-TRONIC': 'RT',
'9G-TRONIC': 'RT', '12AT': 'AT', '12АТ': 'AT', '5АТ': 'AT', '7АТ': 'AT', '7AT': 'AT', '6M/T': 'MT', 'PDK': 'RT', '8-ступ АКПП': 'AT',
'8': 'AT', '8АКПП': 'AT', '8 АКПП Tiptronic S': 'RT', '7 АКПП (PDK)': 'RT', '7 АКПП PDK': 'RT', '8 АКПП (PDK)': 'RT', 'АТ': 'AT',
'АT': 'AT', 'МT': 'MT', '0': 'AT', '7 DSG': 'RT', '7DSG': 'RT', '6 DSG': 'RT', '6DSG': 'RT', 'DSG': 'RT', '6A': 'AT', '6А': 'AT', '5M': 'MT',
'A/T': 'AT', 'M/T': 'MT', 'МКП': 'MT', '5М': 'MT', 'М/T': 'MT', ' 7 АКП': 'RT', '7АКП': 'RT', 'А/T': 'AT', '8A': 'AT', 'TDI': 'RT', '9AT': 'AT',
'РЕДУКТОР': 'RT'
}
#Замена значений в столбце 'коробка_передач' с использованием словаря
auto['коробка_передач'] = auto['коробка_передач'].replace(transmission_type)
#Проверка
auto['коробка_передач'].unique()
array(['AT', nan, 'RT', 'MT', '#Н/Д'], dtype=object)
Осталось разобраться с отсутствующими знаячениями, и теми что были утрачены в следствии повреждения данных.
#Условие для выбора значений '#Н/Д' и NaN в столбце 'коробка_передач'
condition = (auto['коробка_передач'] == '#Н/Д') | auto['коробка_передач'].isna()
#Собираем значения в переменную not_transmission
not_transmission = auto.loc[condition]
not_transmission['коробка_передач'].info()
<class 'pandas.core.series.Series'> Int64Index: 3022 entries, 23734 to 39947 Series name: коробка_передач Non-Null Count Dtype -------------- ----- 4 non-null object dtypes: object(1) memory usage: 47.2+ KB
Предлагаю тем же способом что и раннее восстановить данные.
#Группировка по модели и объединение строк с уникальными моделями
transmission = not_transmission.groupby('бренд')['модель'].unique().reset_index()
#Преобразование списков моделей в строки
transmission['модель'] = transmission['модель'].apply(lambda x: ', '.join(x))
transmission
| бренд | модель | |
|---|---|---|
| 0 | ANKAI | HF-D105, HFF6850G |
| 1 | Dong Feng | BWC6665GA5 |
| 2 | Foton | BJ3253DMPKB-AD, BJ1069VDJEA-F1 |
| 3 | Hyundai Truck & Bus | HD 65, HD 78, Universe, HD 35, EX8 |
| 4 | Isuzu | D-MAX, NMR, NPR, NQR, NMS85, NPS |
| 5 | Iveco | Daily, Daily A, Daily V, Tipper |
| 6 | Jac | S3, S5, N120, N75, T6, iev, N56 |
| 7 | Jaguar | I-Pace |
| 8 | MAN | TG |
| 9 | Mazda | 6, CX-5, CX-9 |
| 10 | Mercedes-Benz | V-Class |
| 11 | Mercedes-Benz Trucks | Actros, Setra |
| 12 | Peugeot | 301, Partner Panel Van |
| 13 | Ravon | Nexia R3, R4 |
| 14 | Renault | Duster, Sandero, Kaptur, Koleos, Logan, Master... |
| 15 | Scania | G-Series, P-Series, R-Series, S-Series |
| 16 | Shacman | SX3258DR384 |
| 17 | Toyota | Corolla, HILUX DC |
| 18 | Volkswagen | Polo |
| 19 | Урал | 4320, 4320-1951-40, 4320-1951-60, 5557, 32551 |
models_and_transmission = {'HF-D105': 'AT', 'HFF6850G': 'AT', 'BWC6665GA5': 'AT', 'BJ3253DMPKB-AD': 'AT', 'BJ1069VDJEA-F1': 'AT', 'HD 65': 'MT', 'HD 78': 'MT',
'Universe': 'MT', 'HD 35': 'MT', 'EX8': 'MT', 'D-MAX': 'MT', 'NMR': 'MT', 'NPR': 'MT', 'NQR': 'MT', 'NMS85': 'MT', 'NPS': 'MT', 'Daily': 'MT',
'Daily A': 'MT', 'Daily V': 'MT', 'Tipper': 'MT', 'S3': 'MT', 'S5': 'MT', 'N120': 'MT', 'N75': 'MT', 'T6': 'MT', 'iev': 'MT', 'N56': 'MT',
'I-Pace': 'MT', 'TG': 'MT', '6': 'MT', 'CX-5': 'MT', 'CX-9': 'MT', 'V-Class': 'MT', 'Actros': 'MT', 'Setra': 'MT', '301': 'MT', 'Partner Panel Van': 'MT',
'Nexia R3': 'MT', 'R4': 'MT', 'Duster': 'MT', 'Sandero': 'MT', 'Kaptur': 'MT', 'Koleos': 'MT', 'Logan': 'MT', 'Master': 'MT', 'Dokker': 'MT', 'Arkana': 'MT',
'G-Series': 'MT', 'P-Series': 'MT', 'R-Series': 'MT', 'S-Series': 'MT', 'SX3258DR384': 'MT', 'Corolla': 'RT', 'HILUX DC': 'RT', 'Polo': 'RT', '4320': 'RT',
'4320-1951-40': 'RT', '4320-1951-60': 'RT', '5557': 'RT', '32551': 'RT'
}
#Обновляем столбец "коробка_передач" в датасете auto с использованием словаря
auto['коробка_передач'] = auto['коробка_передач'].fillna(auto['модель'].map(models_and_transmission))
#Проверка
auto['коробка_передач'].unique()
array(['AT', 'MT', 'RT', '#Н/Д'], dtype=object)
t = auto.query('коробка_передач == "#Н/Д"')
t
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 31148 | 2019 | Февраль | toyota motor kazakhstan | Toyota | Corolla | 2019 | Турция | Б | #Н/Д | #Н/Д | Нур-Султан | физ. лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс | |
| 31149 | 2019 | Февраль | toyota motor kazakhstan | Toyota | Corolla | 2019 | Турция | Б | #Н/Д | #Н/Д | Нур-Султан | физ. лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс | |
| 32670 | 2019 | Апрель | toyota motor kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Б | #Н/Д | #Н/Д | Алматы | юр. лицо | 1 | 30870.28194 | 30870.28194 | г.Алматы | Пикапы | Пикап | |
| 33070 | 2019 | Июль | toyota motor kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Б | #Н/Д | #Н/Д | Атырау | физ. лицо | 1 | 27012.45730 | 27012.45730 | Атырауская область | Пикапы | Пикап |
Те же строки что и раннее.... Снова съехали значения, и не сохранились прошлые. Я пока это оставлю как есть, посмотрим что можно с этим сделать потом.
#Привод
auto['тип_привода'].unique()
array(['MT', 'AT', 'передний', 'FWD', 'quattro', 'Задний', 'Полный',
'AWD', 'Передний', '4WD', '4х2.2', nan, 'RWD', '2 WD', '2WD',
'4 WD', '4X4', '4х4', '4x4', '4x2', '4х2', '4X2', 'Астана',
'Передний (FF)', '0', 'FF', '#Н/Д', 'полный', '4Motion'],
dtype=object)
Астану запихать в регион, остальное классифицировать.
#Список со старыми значениями
transmission_list = ['MT', 'AT', 'передний', 'FWD', 'quattro', 'Задний', 'Полный',
'AWD', 'Передний', '4WD', '4х2.2', 'RWD', '2 WD', '2WD',
'4 WD', '4X4', '4х4', '4x4', '4x2', '4х2', '4X2', 'Передний (FF)',
'0', 'FF', 'полный', '4Motion']
#Новый список со значениями
drive_code_list = []
for transmission in transmission_list:
if transmission in ['FWD', 'передний', 'Передний (FF)', '2WD']:
drive_code_list.append('FWD')
elif transmission in ['Задний', 'RWD']:
drive_code_list.append('RWD')
elif transmission in ['Полный', 'AWD', '4WD', '4X4', '4х4', '4x4', '4x2', '4х2', '4X2', 'quattro', 'полный', '4Motion']:
drive_code_list.append('AWD')
elif transmission in ['AT', 'Автоматический привод']:
drive_code_list.append('AWD')
else:
drive_code_list.append(np.nan)
#Заменяем значения в столбце "тип привода" в датафрейме auto
auto['тип_привода'] = auto['тип_привода'].replace(dict(zip(transmission_list, drive_code_list)))
#Убираем из столбца Астану
auto.loc[auto['тип_привода'] == 'Астана', 'тип_привода'] = np.nan
auto.loc[auto['регион'] == 'Астана', 'регион'] = np.nan
#Проверка значений
auto['тип_привода'].unique()
array([nan, 'AWD', 'FWD', 'RWD', '#Н/Д'], dtype=object)
Создам датасет с отсутствующими и поврежденными данными
not_drive = auto[auto['тип_привода'].isin(['#Н/Д', np.nan])]
Заполним значения по моделям
#Проверка поврежденных значений
n = not_drive.query('тип_привода == "#Н/Д"')
n
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 31148 | 2019 | Февраль | toyota motor kazakhstan | Toyota | Corolla | 2019 | Турция | Б | #Н/Д | #Н/Д | Нур-Султан | физ. лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс | |
| 31149 | 2019 | Февраль | toyota motor kazakhstan | Toyota | Corolla | 2019 | Турция | Б | #Н/Д | #Н/Д | Нур-Султан | физ. лицо | 1 | 42316.46043 | 42316.46043 | г.Нур-Султан | Легковые автомобили | C класс | |
| 32670 | 2019 | Апрель | toyota motor kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Б | #Н/Д | #Н/Д | Алматы | юр. лицо | 1 | 30870.28194 | 30870.28194 | г.Алматы | Пикапы | Пикап | |
| 33070 | 2019 | Июль | toyota motor kazakhstan | Toyota | HILUX DC | 2019 | Таиланд | Б | #Н/Д | #Н/Д | Атырау | физ. лицо | 1 | 27012.45730 | 27012.45730 | Атырауская область | Пикапы | Пикап |
Те же проблемные модели) пожалуй, я от них избавлюсь
Надо сформировать список с моделями для заполнения его данными.
#Список уникальных моделей с отсутствующими значениями
drive_type_dict = {
'Duster': 'FWD', 'Sandero': 'FWD', 'A3': 'AWD', 'A4': 'AWD', 'A6': 'AWD', 'A7': 'AWD', 'A8': 'AWD',
'Q5': 'AWD', 'Q7': 'AWD', '3 серия': 'RWD', '5 серия': 'RWD', '6 серия': 'RWD', '7 серия': 'RWD',
'X1': 'AWD', 'X3': 'AWD', 'X4': 'AWD', 'X5': 'AWD', 'X6': 'AWD', 'X7': 'AWD', 'Z4': 'RWD',
'Aveo': 'FWD', 'Captiva': 'AWD', 'Niva': '4WD', 'Tahoe': '4WD', 'Tracker': 'FWD', 'BS 106 A': 'FWD',
'Fiesta': 'FWD', 'Mondeo': 'FWD', 'BJ3253DMPKB-AD': 'RWD', '2217': 'RWD', '2310': 'RWD', '2705': 'RWD',
'2752': 'RWD', '3221': 'RWD', '3302': 'RWD', '3308': 'RWD', '3309': 'RWD', 'Next': 'RWD',
'Accent': 'FWD', 'Creta': 'FWD', 'Elantra': 'FWD', 'Santa Fe': 'AWD', 'Sonata': 'FWD', 'TQ-1/H-1': 'RWD',
'County': 'RWD', 'H350': 'RWD', 'HD 170': 'RWD', 'HD 65': 'RWD', 'HD 78': 'RWD', 'Universe': 'RWD',
'Tucson': 'AWD', 'Q50': 'AWD', 'QX50': 'AWD', 'QX60': 'AWD', 'QX80': 'AWD', 'D-MAX': '4WD',
'NMR': 'RWD', 'NPR': 'RWD', 'Daily': 'RWD', 'Daily A': 'RWD', 'Daily V': 'RWD', 'Stralis': 'RWD',
'Tipper': 'RWD', 'S3': 'RWD', 'S5': 'RWD', 'F-Pace': 'AWD', 'F-Type': 'RWD', 'XE': 'RWD',
'XF': 'RWD', 'XJ': 'RWD', '4308': 'RWD', '4311': 'RWD', '43118': 'RWD', '43253': 'RWD',
'43502': 'RWD', '44108': 'RWD', '45142': 'RWD', '45143': 'RWD', '53215': 'RWD', '53504': 'RWD',
'53605': 'RWD', '54115': 'RWD', '5490': 'RWD', '65111': 'RWD', '65115': 'RWD', '65116': 'RWD',
'65117': 'RWD', '6520': 'RWD', '65206': 'RWD', '65225': 'RWD', '66052': 'RWD', '6606': 'RWD',
'Cerato': 'FWD', 'Optima': 'FWD', 'Picanto': 'FWD', 'Quoris': 'FWD', 'Rio': 'FWD', 'Sorento': 'AWD',
'Soul': 'FWD', 'Sportage': 'AWD', '4x4': '4WD', 'Granta': 'FWD', 'Kalina': 'FWD', 'Largus': 'FWD',
'Vesta': 'FWD', 'XRAY': 'FWD', 'ВИС': 'RWD', 'Discovery': 'AWD', 'Discovery Sport': 'AWD',
'Range Rover': 'AWD', 'Range Rover Evoque': 'AWD', 'Range Rover Sport': 'AWD', 'ES': 'FWD',
'GX': 'AWD', 'LS': 'RWD', 'LX': 'AWD', 'NX': 'AWD', 'RX': 'AWD', 'RXH': 'AWD', 'Murman': 'FWD',
'Solano': 'FWD', 'X50': 'FWD', 'X60': 'FWD', 'TG': 'RWD', '6': 'FWD', 'CX-5': 'AWD', 'A-Class': 'FWD',
'C-Class': 'RWD', 'CLA-Class': 'FWD', 'CLS-Class': 'RWD', 'E-Class': 'RWD', 'G-Class': 'AWD',
'GLA-Class': 'FWD', 'GLC-Class': 'AWD', 'GLE-Class': 'AWD', 'GLS-Class': 'AWD', 'S-Class': 'RWD',
'Actros': 'RWD', 'Sprinter': 'RWD', 'Tourismo': 'RWD', 'V-Class': 'RWD', 'Vito': 'RWD', 'Countryman': 'AWD',
'ASX': 'AWD', 'Outlander': 'AWD', 'Pajero IV': '4WD', 'Pajero Sport': '4WD', 'Almera': 'FWD',
'Juke': 'FWD', 'Murano': 'AWD', 'Qashqai': 'FWD', 'Terrano': '4WD', 'X-Trail': '4WD', '301': 'FWD',
'Partner Panel Van': 'FWD', '911 Carrera S': 'RWD', 'Cayenne': 'AWD', 'Macan': 'AWD', 'Panamera': 'RWD',
'Nexia R3': 'FWD', 'R4': 'FWD', 'Kaptur': 'FWD', 'Koleos': '4WD', 'Logan': 'FWD', 'Master': 'RWD',
'G-Series': 'RWD', 'P-Series': 'RWD', 'R-Series': 'RWD', 'Octavia': 'FWD', 'Rapid': 'FWD', 'Superb': 'AWD',
'Forester': 'AWD', 'Legacy': 'AWD', 'Outback': 'AWD', 'XV': 'AWD', 'Camry': 'FWD', 'Corolla': 'FWD',
'HIGHLANDER': 'AWD', 'HILUX DC': '4WD', 'LC Prado': '4WD', 'LC200': '4WD', 'RAV4': 'AWD', '2206': 'RWD',
'3151': 'RWD', '3303': 'RWD', '3741': 'RWD', '3909': 'RWD', '3962': 'RWD', 'Cargo': 'RWD', 'Patriot': '4WD',
'Patriot Pickup': '4WD', 'Amarok': '4WD', 'Caddy Kasten ': 'FWD', 'Caddy Maxi Kombi': 'FWD', 'Caravelle': 'AWD',
'Jetta': 'FWD', 'Multivan': 'AWD', 'Polo': 'FWD', 'Tiguan': 'AWD', 'Touareg': 'AWD', 'Transporter': 'RWD',
'Transporter Kasten': 'RWD', 'XC90': 'AWD', '4320': 'RWD', '4320-1951-40': 'RWD', '4320-1951-60': 'RWD',
'5557': 'RWD', 'MYWAY': 'FWD', 'CX-9': 'AWD', 'HD 35': 'RWD', 'Range Rover Velar': 'AWD', 'BS 106 D': 'FWD',
'Kodiaq': 'AWD', 'Escalade': 'AWD', 'GLC Coupe': 'AWD', 'X200': '4WD', 'E-PACE': 'AWD', 'Dokker': 'FWD',
'Eclipse Cross': 'AWD', 'X70': 'FWD', 'N120': 'RWD', 'N75': 'RWD', 'T6': 'AWD', 'SX3258DR384': 'RWD',
'iev': 'FWD', 'S-Series': 'RWD', 'NQR': 'RWD', 'X2': 'AWD', 'S90': 'AWD', 'XC60': 'AWD', 'C-HR': 'FWD',
'300': 'RWD', 'XC40': 'AWD', 'N56': 'RWD', 'XT5': 'AWD', '500': 'FWD', 'Stinger': 'RWD', 'Hatch': 'FWD',
'Traverse': 'AWD', 'NMS85': 'RWD', 'BJ1069VDJEA-F1': 'RWD', 'HD 79': 'RWD', 'BWC6665GA5': 'RWD',
'i8': 'AWD', 'UX': 'AWD', '8 серия': 'RWD', 'Cabrio': 'FWD', 'HF-D105': 'FWD', 'NPS': 'RWD', 'Q8': 'AWD',
'RS5': 'AWD', 'Teramont': 'AWD', '5299': 'RWD', 'I-Pace': 'AWD', 'S7': 'AWD', '45141': 'RWD', '32551': 'RWD',
'BC 211 MA': 'RWD', 'EX8': 'RWD', 'BC 095': 'RWD', 'Camaro': 'RWD', 'HFF6850G': 'RWD', 'Transporter Kombi ': 'RWD'
}
#Обновляем столбец "тип_привода" в датасете auto с использованием словаря
auto['тип_привода'] = auto['тип_привода'].fillna(auto['модель'].map(drive_type_dict))
auto = inform(auto)
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 23723 | 2019 | Январь | renault россия | Renault | Duster | 2019 | Российская Федерация | Б | 2 | AT | FWD | Уральск | юр. лицо | 1 | 12249.61125 | 12249.61125 | Западно-Казахстанская область | Внедорожники | Субкомпактные SUV |
| 23724 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Нур-Султан | юр. лицо | 1 | 12249.61125 | 12249.61125 | г.Нур-Султан | Внедорожники | Субкомпактные SUV |
| 23725 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Нур-Султан | юр. лицо | 1 | 12249.61125 | 12249.61125 | г.Нур-Султан | Внедорожники | Субкомпактные SUV |
| 23726 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Кызылорда | юр. лицо | 1 | 12249.61125 | 12249.61125 | Кызылординская область | Внедорожники | Субкомпактные SUV |
| 23727 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | FWD | Караганда | юр. лицо | 1 | 12249.61125 | 12249.61125 | Карагандинская область | Внедорожники | Субкомпактные SUV |
<class 'pandas.core.frame.DataFrame'> Int64Index: 39465 entries, 23723 to 39965 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 год 39465 non-null int64 1 месяц 39465 non-null object 2 компания 39465 non-null object 3 бренд 39465 non-null object 4 модель 39465 non-null object 5 год_выпуска 39465 non-null int32 6 производитель 39465 non-null object 7 вид_топлива 39465 non-null object 8 объем_двигателя 39465 non-null object 9 коробка_передач 39465 non-null object 10 тип_привода 39394 non-null object 11 регион 39465 non-null object 12 тип_клиента 39465 non-null object 13 количество 39465 non-null int32 14 цена_usd 39465 non-null float64 15 продажа_usd 39465 non-null float64 16 область 39465 non-null object 17 сегментация 39465 non-null object 18 класс 39465 non-null object dtypes: float64(2), int32(2), int64(1), object(14) memory usage: 6.7+ MB Количество дубликатов: 22070 Число пропусков: год 0 месяц 0 компания 0 бренд 0 модель 0 год_выпуска 0 производитель 0 вид_топлива 0 объем_двигателя 0 коробка_передач 0 тип_привода 71 регион 0 тип_клиента 0 количество 0 цена_usd 0 продажа_usd 0 область 0 сегментация 0 класс 0 dtype: int64 Доля пропусков: год 0.000000 месяц 0.000000 компания 0.000000 бренд 0.000000 модель 0.000000 год_выпуска 0.000000 производитель 0.000000 вид_топлива 0.000000 объем_двигателя 0.000000 коробка_передач 0.000000 тип_привода 0.179906 регион 0.000000 тип_клиента 0.000000 количество 0.000000 цена_usd 0.000000 продажа_usd 0.000000 область 0.000000 сегментация 0.000000 класс 0.000000 dtype: float64 1
На этом предобработка завершена. Остались последние штрихи. Были удалены лишние столбцы дублирующие информацию, оставшиеся приведены к snake_case стилю для удобства работы с ними, числа приведены к нужным типам данных, неявные дубликаты заменены на корректные значения, восстановлены и сокращены (для оптимзации скорости загрузки датасета) типы привода к единому обозначению, сокращены (для опримизации скорости загрузки датасета) обозначения вида топлива, заполнены пропуски значений с задачей максимально сберечь данные в датасете.
Мной принято решение удалить пропущенные строки в столбце тип привода (0.18% от общего объема данных, мы ничего не теряем), т.к. роли для анализа они не играют никакой а эстетику портят :) Полные дубли которые оказались в датасете из-за отсутствия id индексации строк я оставляю, без них исказится дальнейший анализ.
#Избавлюсь от 0.18% пропусков в типе привода
clean_auto = auto.dropna()
#Инфо о чистом датасете
clean_auto = inform(clean_auto)
| год | месяц | компания | бренд | модель | год_выпуска | производитель | вид_топлива | объем_двигателя | коробка_передач | тип_привода | регион | тип_клиента | количество | цена_usd | продажа_usd | область | сегментация | класс | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 23723 | 2019 | Январь | renault россия | Renault | Duster | 2019 | Российская Федерация | Б | 2 | AT | FWD | Уральск | юр. лицо | 1 | 12249.61125 | 12249.61125 | Западно-Казахстанская область | Внедорожники | Субкомпактные SUV |
| 23724 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Нур-Султан | юр. лицо | 1 | 12249.61125 | 12249.61125 | г.Нур-Султан | Внедорожники | Субкомпактные SUV |
| 23725 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Нур-Султан | юр. лицо | 1 | 12249.61125 | 12249.61125 | г.Нур-Султан | Внедорожники | Субкомпактные SUV |
| 23726 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | AWD | Кызылорда | юр. лицо | 1 | 12249.61125 | 12249.61125 | Кызылординская область | Внедорожники | Субкомпактные SUV |
| 23727 | 2019 | Январь | renault россия | Renault | Duster | 2018 | Российская Федерация | Б | 2 | AT | FWD | Караганда | юр. лицо | 1 | 12249.61125 | 12249.61125 | Карагандинская область | Внедорожники | Субкомпактные SUV |
<class 'pandas.core.frame.DataFrame'> Int64Index: 39394 entries, 23723 to 39950 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 год 39394 non-null int64 1 месяц 39394 non-null object 2 компания 39394 non-null object 3 бренд 39394 non-null object 4 модель 39394 non-null object 5 год_выпуска 39394 non-null int32 6 производитель 39394 non-null object 7 вид_топлива 39394 non-null object 8 объем_двигателя 39394 non-null object 9 коробка_передач 39394 non-null object 10 тип_привода 39394 non-null object 11 регион 39394 non-null object 12 тип_клиента 39394 non-null object 13 количество 39394 non-null int32 14 цена_usd 39394 non-null float64 15 продажа_usd 39394 non-null float64 16 область 39394 non-null object 17 сегментация 39394 non-null object 18 класс 39394 non-null object dtypes: float64(2), int32(2), int64(1), object(14) memory usage: 5.7+ MB Количество дубликатов: 22019 Число пропусков: год 0 месяц 0 компания 0 бренд 0 модель 0 год_выпуска 0 производитель 0 вид_топлива 0 объем_двигателя 0 коробка_передач 0 тип_привода 0 регион 0 тип_клиента 0 количество 0 цена_usd 0 продажа_usd 0 область 0 сегментация 0 класс 0 dtype: int64 Доля пропусков: год 0.0 месяц 0.0 компания 0.0 бренд 0.0 модель 0.0 год_выпуска 0.0 производитель 0.0 вид_топлива 0.0 объем_двигателя 0.0 коробка_передач 0.0 тип_привода 0.0 регион 0.0 тип_клиента 0.0 количество 0.0 цена_usd 0.0 продажа_usd 0.0 область 0.0 сегментация 0.0 класс 0.0 dtype: float64 1
#Дашборд с чистыми данными (чтобы открыть, нужно убрать #)
my_report = sv.analyze(clean_auto)
#my_report.show_html()
Таким образом проведена комплексная очистка датасета и восстановление утраченных данных, с попыткой сохранить максимум имеющейся информации. Проводя предобработку у меня появилось несколько рекомендаций для сбора, чтобы в будущем повысить качество данных, ускорить предобработку аналитикам, а так же оптимизировать ввод информации сотрудникам автосалонов.
Рекомендую ввести индексацию строк присваивая уникальный id для каждой. Это избавит массив данных от множества явных дубликатов, искать информацию станет легче.
Рекомендую заблокировать возможность ручного ввода информации о характеристиках автомобиля. Необходимо сделать выпадающее окно с вариантами выбора вида топлива, типа привода, коробки передач. Таким образом мы получим стандарт введения информации в базу данных, что позволит быстро ориентироваться в них и оперативно собирать статистику. Так же это облегчит жизнь аналитикам данных.
Рекомендую вести учет информации в единой БД. При объединении данных хранящихся на разных сервисах/облаках неизбежно возникают съехавшие значения, ошибки при выгрузке данных, а так же может быть утеряна часть этих данных. Это позволит иметь быстрый доступ к архивам без надобности склеивать данные, убережет их от возникновения части ошибок при выгрузке.
Из 39 965 сток изначального датасета auto осталось 39 950 строк в датасете clean_auto. Данные не пострадали, очищенный датасет может использоваться для построения дашборда.
#Название датасета в переменную csv_filename
csv_filename = 'clean_auto.csv'
clean_auto.to_csv(csv_filename, index=False) #
#Создание ссылки для скачивания
download_link = FileLink(csv_filename)
#Отображение ссылки для загрузки датасета
download_link
В исследовательсвом анализе данных я постараюсь раскрыть несколько важных моментов при анализе авторынка разделив его на коммерческий и некоммерческий транспорт. План действий следующий:
Продажи по брендам, сегментам коммерческого и некоммерческого авто
Модели-лидеры на рынке
Продажи по регионам
Продажи автоцентров
#Создание нового столбца с датой, для того чтобы корректно отображать графики
#Преобразование года к строковому типу, месяц в нижний регистр
clean_auto['год'] = clean_auto['год'].astype(str)
clean_auto['месяц'] = clean_auto['месяц'].str.lower()
#Словарь для замены названий месяцев
months_list = ['январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь']
new_months = list(range(1, 10))
months_change_dict = {k: '0' + str(v) for k, v in zip(months_list, new_months)}
#Применение словаря к столбцу 'месяц'
clean_auto['месяц'] = clean_auto['месяц'].str.lower().map(months_change_dict)
#Объединение 'год' и 'месяц' в 'дата_продажи'
clean_auto['дата_продажи'] = clean_auto['год'] + '-' + clean_auto['месяц']
#Преобразование 'дата_продажи' в datetime
clean_auto['дата_продажи'] = pd.to_datetime(clean_auto['дата_продажи'], errors='coerce')
clean_auto['дата_продажи'].unique()
array(['2019-01-01T00:00:00.000000000', '2019-05-01T00:00:00.000000000',
'2019-08-01T00:00:00.000000000', '2019-04-01T00:00:00.000000000',
'2019-07-01T00:00:00.000000000', '2019-02-01T00:00:00.000000000',
'2019-06-01T00:00:00.000000000', '2019-09-01T00:00:00.000000000',
'2019-03-01T00:00:00.000000000'], dtype='datetime64[ns]')
#Сразу разделю транспорт на коммерцию и бытовое пользование, эт в будущем пригодится
#Здесь живет коммерческий транспорт
auto_com = clean_auto[clean_auto['сегментация'] == 'Коммерческие автомобили']
#Народная выборка! Все для людей :)
auto_child = clean_auto[clean_auto['сегментация'] != 'Коммерческие автомобили']
#Создам сводную таблицу с количеством продаж каждого сегмента транспорта
all_auto = clean_auto.groupby('сегментация')['количество'].sum().reset_index()
all_auto = all_auto.sort_values(by='количество', ascending=False)
all_auto
| сегментация | количество | |
|---|---|---|
| 2 | Легковые автомобили | 23288 |
| 0 | Внедорожники | 21458 |
| 1 | Коммерческие автомобили | 5102 |
| 3 | Минивэны | 1819 |
| 4 | Пикапы | 975 |
#Построение графика отображающего сводную таблицу
fig = px.bar(all_auto, x='сегментация', y='количество', color='сегментация', text = 'количество',
color_discrete_sequence=px.colors.qualitative.Prism)
fig.update_layout(title='Проданные автомобили разбитые по сегментам',
xaxis_title='Сегмент',
yaxis_title='количество продаж')
fig.show()
Чаще всего приобретались легковые авто и внедорожники. Это логично, т.к. салоны торгующие авто больше направлены на аудиторию гражданского населения, нежели на удовлетворение спроса коммерческих нужд. Более того, крупные коммерческие организации заключают контракт на прямую с заводами производителями авто, те в свою очередь могут предлагать более выгодные условия для организации нежели диллер.
Минивэны и пикапы автомобили специфичные. Например, минивэн может заинтересовать семьи с тремя и более детьми (коих не так уж и много на этой планете), пикапы удобны для жизни за городом, в местностях с тяжелой проходимостью, для людей нуждающихся в относительно большой грузоподъемности и мощности авто. Отсюда и наблюдаем не такую высокую популярность данных сегментов.
Рассмотрим самые популярные бренды автомобилей пользующиеся спросом у населения. Здесь понадобится уже собранный датафрейм без участия коммерческого транспорта.
#Таблица с брендами. Пусть это будет топ 10 брендов
brend = auto_child.groupby('бренд')['количество'].sum().reset_index()
brend = brend.sort_values(by='количество', ascending=False)
brend = brend.head(10)
brend
| бренд | количество | |
|---|---|---|
| 11 | Lada | 11092 |
| 26 | Toyota | 10745 |
| 5 | Hyundai | 10168 |
| 10 | Kia | 2358 |
| 22 | Ravon | 1785 |
| 23 | Renault | 1741 |
| 8 | Jac | 1686 |
| 19 | Nissan | 1664 |
| 13 | Lexus | 1206 |
| 24 | Skoda | 791 |
#Построение графика отображающего сводную таблицу
fig = px.bar(brend, x='бренд', y='количество', color='бренд', text = 'количество',
color_discrete_sequence=px.colors.qualitative.Prism)
fig.update_layout(title='Топ авто по брендам у населения',
xaxis_title='Бренды',
yaxis_title='количество продаж')
fig.show()
Я удивлен. Лада фаворит:) Видно что с большим отрывом лидируют такие бренды как Lada, Tayota, Hyundai. Это можно объяснить широкой доступностью расходников и запчастей на данные марки, привлекательной ценой (в этом плане выигрывает Лада у всех), а у Тайоты и Хёндая высочайший срок службы. Эти автомобили не дорогие в обслуживании, долговечные (долговечность не про Ладу), а от того и покорили сердца населения. Рассматривать другие бренды не счичтаю целесообразным, т.к. разница в объеме продаж колоссальна.
Рассмотрим так же бренды коммерческих авто.
#Таблица с брендами. Пусть это будет топ 10 брендов
brend_com = auto_com.groupby('бренд')['количество'].sum().reset_index()
brend_com = brend_com.sort_values(by='количество', ascending=False)
brend_com = brend_com.head(10)
brend_com
| бренд | количество | |
|---|---|---|
| 4 | GAZ | 1821 |
| 10 | KAMAZ | 877 |
| 17 | UAZ | 844 |
| 0 | ANKAI | 300 |
| 9 | Jac | 192 |
| 2 | Dong Feng | 160 |
| 1 | Daewoo | 146 |
| 7 | Isuzu | 125 |
| 6 | Hyundai Truck & Bus | 109 |
| 16 | Shacman | 101 |
#Построение графика отображающего сводную таблицу
fig = px.bar(brend_com, x='бренд', y='количество', color='бренд', text = 'количество',
color_discrete_sequence=px.colors.qualitative.Prism)
fig.update_layout(title='Топ авто по брендам у коммерции',
xaxis_title='Бренды',
yaxis_title='количество продаж')
fig.show()
GAZ, KAMAZ, UAZ самые популярные авто для коммерции. GAZ пользуется спросом у спецслужб (скорая, полиция), Камазы распространены в строительных организациях и транспортных компаниях, Уазики гибки в использовании, их линейка коммерческого транспорта имеет как авто для перемещения пассажиров, так и грузовые авто до 3.5 тон.
ANKAI, Dong Feng, Daewoo, Isuzu - это пассажирские автобусы. Автопарк пополняют обычно по мере списания старых авто :) потому продажи не такие активные.
Теперь я рассмотрю динамику продаж транспорта в денежном эквиваленте за весь временной период который мы имеем в датасете.
#Подготовка данных для построения графика
line_graph = clean_auto.groupby('дата_продажи')['продажа_usd'].sum().reset_index()
cum_line_graph = clean_auto.groupby('дата_продажи')['продажа_usd'].sum().reset_index()
cum_line_graph['продажа_usd'] = cum_line_graph['продажа_usd'].cumsum()
#Создаю график с динамикой и объемом продаж
fig, ax1 = plt.subplots(figsize=(12, 6))
#Динамика
ax1.plot(line_graph['дата_продажи'],
line_graph['продажа_usd']/1000000,
linewidth=2,
color='crimson',
marker='s',
label='Динамика продаж по месяцам')
ax1.set_xlabel('Месяц продажи')
ax1.set_ylabel('Объем продаж, млн.$', color='crimson')
ax1.tick_params(axis='y', labelcolor='crimson')
#Подписи для динамики
for x, y in zip(line_graph['дата_продажи'], line_graph['продажа_usd']/1000000):
ax1.annotate(f'{y:.2f}', (x, y), textcoords="offset points", xytext=(-10,5), ha='center')
#Создаем вторую ось Y
ax2 = ax1.twinx()
#Емкость рынка
ax2.plot(cum_line_graph['дата_продажи'],
cum_line_graph['продажа_usd']/1000000,
linewidth=2,
color='#0492C2',
marker='o',
linestyle='--',
label='Динамика емкости рынка')
#Подписи для емкости
for x, y in zip(cum_line_graph['дата_продажи'], cum_line_graph['продажа_usd']/1000000):
ax2.annotate(f'{y:.2f}', (x, y), textcoords="offset points", xytext=(-5,0), ha='right', va='baseline', color='#0492C2')
#Названия осей и графика
plt.title('Динамика объема продаж автомобилей в Казахстане в 2019 году (млн.USD)')
plt.xlabel('Месяц продажи')
plt.ylabel('Объем продаж, млн.$')
plt.xticks()
ax2.set_ylabel('Динамика емкости рынка', color='#0492C2')
ax2.tick_params(axis='y', labelcolor='#0492C2')
fig.tight_layout()
plt.show()
Таким образом мы видим что динамика емкости рынка к сентябрю 2019го составила 1 миллиард 321 миллион долларов, прирост был плавным на протяжении всего периода. А вот объем продаж показывает немного другую картину. Самый провальный оказался февраль (109.59 млн за месяц), и это можно объяснить закономерностью продаж в большинстве сфер торговли (февраль как правило в ряде сфер считается месяцем с самым низким показателем продаж), самый высокий показатель в июле (199.68 млн за месяц). с февраля по июнь наблюдается относительно равная картина восстановления объема продаж перед грядущей аномалией, следом после всплеска произошло падение до 153.38 млн в августе, и график снова постепенно стал возвращаться в норму чему следует увеличившийся объем в сентябре до 157.61 млн.
В 2019 году казахстанский авторынок показал самый высокий результат за последние семь лет – официальные дилеры реализовали 123 778 автомобилей. Однако, конкретная причина всплеска продаж в июле 2019 года не была мной найдена. Возможно, всплеск продаж был связан с общими тенденциями роста в этом году, ведь было реализовано 76 217 новых автомобилей, а это на 22% больше чем в 2018 году. Поскольку самыми продаваемыми моделями в 2019 году в Казахстане стали автомобили Toyota Camry, я так же могу предположить что это связано с поставкой диллерам в салоны этой модели... Ажиотаж к покупке данной модели мог привести к повышенной активности населения в июле, но проверить информацию не предоставляется возможным.
👇 Источники информации ниже по ссылкам 👇
Считаю целесообразным изучить информацию о продажах по диллерам. Это даст понимание где и у кого лучше продаются авто. Изучив это можно начинать разрабатывать стратегию по увеличению объема продаж и захвата целевой аудитории.
#Группировка компаний и количества продаж
company_child = clean_auto.groupby('компания')['количество'].sum().reset_index()
company_child = company_child.sort_values(by='количество', ascending=False)
company_child = company_child.head(10)
company_child
| компания | количество | |
|---|---|---|
| 25 | бипэк авто | 15132 |
| 19 | toyota motor kazakhstan | 11951 |
| 2 | astana motors | 10169 |
| 26 | вираж | 2909 |
| 0 | allur auto | 2415 |
| 12 | nissan manufacturing rus | 1760 |
| 14 | renault россия | 1741 |
| 13 | ravon motors kazakstan | 1507 |
| 30 | тк камаз | 878 |
| 10 | mercur auto | 650 |
#Для первого круга топ-3 компании
labels_top3 = company_child['компания'][:3]
values_top3 = company_child['количество'][:3]
#Остальные компании для второго круга
labels_rest = company_child['компания'][3:]
values_rest = company_child['количество'][3:]
#Круговая диаграмма с топ-3 компаниями
fig_top3 = go.Figure(go.Pie(labels=labels_top3, values=values_top3,
textinfo='label+percent',
marker=dict(colors=px.colors.sequential.GnBu_r),
name="Доля продаж топ-3 компаний",
insidetextorientation='radial'))
#Круговая диаграмма с остальными компаниями
fig_rest = go.Figure(go.Pie(labels=labels_rest, values=values_rest,
textinfo='label+percent',
marker=dict(colors=px.colors.sequential.GnBu_r),
name="Доля продаж остальных компаний",
insidetextorientation='radial'))
#Две диаграммы на одном графике
fig = make_subplots(1, 2, specs=[[{'type':'domain'}, {'type':'domain'}]],
subplot_titles=['Доля продаж топ-3 компаний', 'Доля продаж остальных компаний'])
#Добавление диаграмм на график
fig.add_trace(fig_top3.data[0], 1, 1)
fig.add_trace(fig_rest.data[0], 1, 2)
#Управление размерами и расположением заголовка
fig.update_layout(showlegend=True, title_text="Доли продаж по компаниям", height=600, width=1200, title_x=0.5)
fig.show()
Бипэк авто, крупнейший холдинг имеющий самую большую долю авторынка Казахстана (40.6%). На тот момент ничего не предвещало беды, но уже в конце 2019 Бипэк уходит с рынка. Помимо нблюдаем дистрибьютора Tayota motor kazahstan (32.1% рынка) и astana motors (27.3%). Доля остальных диллеров существенно ниже, рассматривать их не имеет целесообразности.
Т.к. нас интересует Mercur Auto, следует отметить что в топе этот диллер находится на последнем месте, занимая лишь 5.5% рынка.
#Таблица с топом регионов где осуществлялись продажи
top_region = clean_auto.groupby('регион')['количество'].sum().reset_index()
top_region = top_region.sort_values(by='количество', ascending=False)
top_region = top_region.head(10)
top_region
| регион | количество | |
|---|---|---|
| 2 | Алматы | 13533 |
| 11 | Нур-Султан | 9976 |
| 23 | Шымкент | 3728 |
| 3 | Атырау | 3311 |
| 8 | Костанай | 3156 |
| 5 | Караганда | 2843 |
| 21 | Уральск | 2128 |
| 22 | Усть-Каменогорск | 2096 |
| 0 | Актау | 2049 |
| 1 | Актобе | 1794 |
#Строим самый красивый на свете график
fig = px.bar(top_region, x='количество', y='регион', color='регион', text ='количество',
color_discrete_sequence=px.colors.qualitative.Prism)
fig.update_layout(title='Общее количество продаж по регионам',
xaxis_title='Количество продаж',
yaxis_title='Названия регионов')
fig.show()
Лидеры общих продаж по регионам Алматы (13533 продаж) и Нур-Султан (9876 продаж). В средних значениях от 3156 до 3728 продаж держатся Костанай, Атырау, и Шымкент.
Анализ положения Меркур Авто позволит сделать выводы, и построить рекомендации для улучшения показателей продаж, а так же понимания на что стоит обратить внимание в дальнейшем.
План действий:
#Фильтрация по компании. Оставим только Меркур Авто
mer_auto = clean_auto.query('компания == "mercur auto"')
#Сводная таблица с общими продажами по месяцам(пригодится для построения графика)
sales_month = mer_auto.groupby('месяц')['продажа_usd'].sum().reset_index()
sales_month['продажа_usd'] = sales_month['продажа_usd'].round(2)
#Общая и средняя выручка
print('Общая выручка:', mer_auto['продажа_usd'].sum().round(2))
print()
print('Средняя выручка в месяц:', round(sales_month['продажа_usd'].mean(), 2))
Общая выручка: 19355275.98 Средняя выручка в месяц: 2150586.22
Общая выручка за весь период с января по сентябрь 2019го года у компании Mercur Auto составила 19 355 276 usd. Средняя ежемесячная выручка составляет 2 150 586 usd.
#Верну месяцам названия, чтобы график выглядел приличнее
sales_month['месяц'] = sales_month['месяц'].replace({'01': 'Январь', '02': 'Февраль', '03': 'Март', '04': 'Апрель',
'05': 'Май', '06': 'Июнь', '07': 'Июль', '08': 'Август', '09': 'Сентябрь'})
sales_month
| месяц | продажа_usd | |
|---|---|---|
| 0 | Январь | 2979406.65 |
| 1 | Февраль | 2949383.66 |
| 2 | Март | 2707627.00 |
| 3 | Апрель | 2667282.58 |
| 4 | Май | 3687779.06 |
| 5 | Июнь | 835751.00 |
| 6 | Июль | 1386826.00 |
| 7 | Август | 1110374.04 |
| 8 | Сентябрь | 1030846.00 |
#Построение графика отображающего сводную таблицу
fig = px.bar(sales_month, x='месяц', y='продажа_usd', color='месяц', text = 'продажа_usd',
color_discrete_sequence=px.colors.qualitative.Prism)
fig.update_layout(title='Общая сумма продаж по месяцам',
xaxis_title='Месяц',
yaxis_title='Сумма продаж')
fig.show()
Выведя график с суммой общих продаж по месяцам наблюдается хороший уровень начала года имеющий слегка понижающийся тренд, затем резкий скачок в мае (3 687 779 usd, самый высокий показатель за весь временной диапазон), и существенная просадка выручки в летне-осенний период. Что послужило причиной аномалии в мае? Пока не могу предположить причины произошедшего, построю график с количеством единиц брендов продаваемых в Меркур Авто, и заодно выведу отдельный график с суммой продаж этих машин в каждом месяце.
#Количество продаваемых авто каждого бренда с суммой выручки
top_auto = mer_auto.groupby('бренд')[['количество', 'продажа_usd']].sum().reset_index()
top_auto['продажа_usd'] = top_auto['продажа_usd'].round(2)
top_auto = top_auto.sort_values(by='продажа_usd', ascending=False)
top_auto
| бренд | количество | продажа_usd | |
|---|---|---|---|
| 2 | Volkswagen | 546 | 10182272.86 |
| 1 | Porsche | 52 | 5113512.70 |
| 0 | Audi | 52 | 4059490.43 |
#Круговые диаграммы с долей по количеству и продажам
#Диаграмма по количеству
fig_quantity = go.Figure(go.Pie(labels=top_auto['бренд'], values=top_auto['количество'],
textinfo='label+percent', marker=dict(colors=px.colors.sequential.RdPu_r)))
#Диаграмма по продажам
fig_sales = go.Figure(go.Pie(labels=top_auto['бренд'], values=top_auto['продажа_usd'],
textinfo='label+percent', marker=dict(colors=px.colors.sequential.RdPu_r)))
#Сетка для размещения диаграмм рядом
fig = make_subplots(rows=1, cols=2, subplot_titles=['Доля по количеству', 'Доля по сумме продаж'],
specs=[[{'type': 'domain'}, {'type': 'domain'}]])
#Добавление диаграмм на сетку
fig.add_trace(fig_quantity.data[0], 1, 1)
fig.add_trace(fig_sales.data[0], 1, 2)
#Регулировка размера графика и центрование заголовка
fig.update_layout(showlegend=True, title_text="Доли продаж по брендам", height=600, width=1200, title_x=0.5)
fig.show()
Фольксваген - он же "народный автомобиль" лидирует и в количестве проданных авто (546 штук), и в сумме продаж (10 182 272 usd) за весь период. Доля продаж по количеству Ауди и Порше всего по 8% каждый (а это по 52 автомобиля продано у каждого бренда), однако доля по сумме продаж у Порше 26.4%, а у Ауди 21%, суммарно чуть меньше половины общего объема, в то время как Фольксваген с огромным перевесом в количестве проданных авто составляет лишь 52.6%.
Это объясняется тем что Порше и Ауди - люксовые автомобили, их стоимость существенно выше чем у моделей Фольксвагена которые выпускаются на широкую аудиторию потребителя. Отсюда такая разница в количестве проданных автомобилей, и разнице в стоимости.
#Сводная таблица с месяцами и марками
month_auto = mer_auto.groupby(['месяц', 'бренд'])['количество'].sum().reset_index()
#Месяца человековыми буквами
month_auto['месяц'] = month_auto['месяц'].replace({'01': 'Январь', '02': 'Февраль', '03': 'Март', '04': 'Апрель',
'05': 'Май', '06': 'Июнь', '07': 'Июль', '08': 'Август', '09': 'Сентябрь'})
month_auto
| месяц | бренд | количество | |
|---|---|---|---|
| 0 | Январь | Audi | 2 |
| 1 | Январь | Porsche | 1 |
| 2 | Январь | Volkswagen | 162 |
| 3 | Февраль | Audi | 2 |
| 4 | Февраль | Porsche | 5 |
| 5 | Февраль | Volkswagen | 119 |
| 6 | Март | Audi | 9 |
| 7 | Март | Porsche | 7 |
| 8 | Март | Volkswagen | 62 |
| 9 | Апрель | Audi | 5 |
| 10 | Апрель | Porsche | 8 |
| 11 | Апрель | Volkswagen | 65 |
| 12 | Май | Audi | 7 |
| 13 | Май | Porsche | 8 |
| 14 | Май | Volkswagen | 138 |
| 15 | Июнь | Audi | 4 |
| 16 | Июнь | Porsche | 5 |
| 17 | Июль | Audi | 10 |
| 18 | Июль | Porsche | 7 |
| 19 | Август | Audi | 7 |
| 20 | Август | Porsche | 7 |
| 21 | Сентябрь | Audi | 6 |
| 22 | Сентябрь | Porsche | 4 |
#График с продажей авто по месяцам
fig = px.bar(month_auto, x='месяц', y='количество', color='бренд', text = 'количество',
color_discrete_sequence=px.colors.qualitative.Prism[2:],
barmode='group', height=550)
fig.update_traces(textposition='outside') #Чтобы количество отображалось над столбцами
#Названия графика
fig.update_layout(title='Продажа автомобилей по месяцам',
xaxis_title='Месяц',
yaxis_title='Количество проданных')
fig.show()
Что ж, открылась картина того почему с января по май хорошо держались продажи, в мае произошел скачок и дальше случился резкий спад выручки. Фольксвагены перестали продаваться :) Как нам известно, они составляли большую часть выручки, и попытка выйти на премиум-сегмент отказавшись от более доступных автомобилей судя по графикам оказалось не лучшей идеей.
#Сводная таблица с количеством продаж по регионам
mer_region = mer_auto.groupby('регион')['количество'].sum().reset_index()
mer_region = mer_region.sort_values(by='количество', ascending=False)
mer_region
| регион | количество | |
|---|---|---|
| 0 | Алматы | 484 |
| 4 | Нур-Султан | 59 |
| 1 | Атырау | 43 |
| 3 | Костанай | 26 |
| 2 | Караганда | 23 |
| 5 | Уральск | 15 |
#Визуализирую регионы с продажами
fig = px.bar(mer_region, x='количество', y='регион', color='регион', text ='количество',
color_discrete_sequence=px.colors.qualitative.Prism[4:])
fig.update_layout(title='Общее количество продаж по регионам',
xaxis_title='Количество продаж',
yaxis_title='Названия регионов')
fig.show()
Больше всего продаж в регионе Алматы (484), он лидирует с большим отрывом от остальных что не удивительно, ведь Алматы самый крупный по численности населения город в Казахстане. Теперь нужно посмотреть какие машины продаются лучше по регионам.
#Сводная таблица с регионами и продаваемыми там брендами
mer_region_auto = mer_auto.groupby(['регион', 'бренд'])['количество'].sum().reset_index()
mer_region_auto
| регион | бренд | количество | |
|---|---|---|---|
| 0 | Алматы | Audi | 43 |
| 1 | Алматы | Porsche | 51 |
| 2 | Алматы | Volkswagen | 390 |
| 3 | Атырау | Volkswagen | 43 |
| 4 | Караганда | Volkswagen | 23 |
| 5 | Костанай | Audi | 2 |
| 6 | Костанай | Volkswagen | 24 |
| 7 | Нур-Султан | Audi | 7 |
| 8 | Нур-Султан | Porsche | 1 |
| 9 | Нур-Султан | Volkswagen | 51 |
| 10 | Уральск | Volkswagen | 15 |
Так как Алматы имеет огромный отрыв в количестве продаж авто - строить единый график с остальными регионами не информативно. Я разделю сводную таблицу на остальные регионы, и отдельно Алматы.
#Только Алматы
only_alm = mer_region_auto.query('регион == "Алматы"')
only_alm = only_alm.sort_values(by='количество', ascending=False)
only_alm
| регион | бренд | количество | |
|---|---|---|---|
| 2 | Алматы | Volkswagen | 390 |
| 1 | Алматы | Porsche | 51 |
| 0 | Алматы | Audi | 43 |
#График с показателями продаж в Алматы
fig_alm = go.Figure(go.Pie(labels=only_alm['бренд'], values=only_alm['количество'],
textinfo='label+percent+value',
marker=dict(colors=px.colors.sequential.GnBu_r),
name="Доля продаж топ-3 компаний"))
#insidetextorientation='radial'))
fig_alm.update_layout(showlegend=True, title_text="Продажи в Алматы", height=600, width=1200, title_x=0.5)
fig_alm.show()
Продано 390 Фольксвагенов, 51 Порш, и 43 Ауди. Алматы превосходит по количеству продаж каждой марки авто все остальные регионы вместе взятые.
#Уберем Алматы
not_alm = mer_region_auto.query('регион != "Алматы"')
not_alm['количество'] = not_alm['количество'].sort_values(ascending=False)
not_alm
| регион | бренд | количество | |
|---|---|---|---|
| 3 | Атырау | Volkswagen | 43 |
| 4 | Караганда | Volkswagen | 23 |
| 5 | Костанай | Audi | 2 |
| 6 | Костанай | Volkswagen | 24 |
| 7 | Нур-Султан | Audi | 7 |
| 8 | Нур-Султан | Porsche | 1 |
| 9 | Нур-Султан | Volkswagen | 51 |
| 10 | Уральск | Volkswagen | 15 |
#График с продажами в регионах без Алматы
fig = px.bar(not_alm, x='регион', y='количество', color='бренд',
title='Продажа автомобилей в остальных регионах',
labels={'регион':'Регион', 'количество':'Количество проданных'},
text = 'количество',
height=550,
color_discrete_sequence=px.colors.qualitative.Prism[1:])
fig.update_traces(textposition='outside') #Чтобы количество отображалось над столбцами
fig.show()
Опять же, в основном продавались Фольксвагены. За весь период только один раз продан Порш в Нур-Султане, и 9 Ауди, два из которых в Костанае и 7 в Нур-Султане.
Эти графики подтверждают что попытка оставить только премиум сегмент откзавшись от доступных авто для широкой аудитории потребителя повлекло за собой резкое падение продаж. Реализация Фольксвагенов составляла львинную долю продаж в каждом из регионов без исключения.
Выводить дополнительные графики с продажами по месяцам в Атырау и Нур-Султане не имеет смысла, т.к. нам уже известно что Фольксвагены продавались до мая месяца.
Исходя из этой информации есть несколько рекомендаций:
Необходимо вернуть в продажу Фольксвагены :) Эти машины пользуются спросом, отказ от них наносит удар по прибыли компании.
Рекомендую остатки Порше и Ауди перевезти в Алматы, и сконцентрироваться на продаже премиум сегмента именно там. С такими показателями продаж реализация премиум сегмента будет лучше.
В случае отказа от Фольксвагенов держать салоны во всех остальных регионах кроме Алматы не целесообразно. Рекомендую их закрыть, таким образом сократив расходы компании на аренду помещений.
BCG анализ позволит взглянуть на продаваемые бренды чуть под другим углом. Будет не лишним доказать преимущество Фольксвагенов для прибыли компании, а так же узнать чем на данном этапе являются продажи Ауди и Порше.
#Сводная таблица с продаваемыми брендами,расчетом общего количества и средней цены для каждого бренда
brand_data = mer_auto.groupby('бренд').agg({'количество': 'sum', 'цена_usd': 'mean'}).reset_index()
#Подготовка данных для построения графика
brand_data['количество'] = (brand_data['количество'] - brand_data['количество'].min()) / (brand_data['количество'].max() - brand_data['количество'].min())
brand_data['цена_usd'] = (brand_data['цена_usd'] - brand_data['цена_usd'].min()) / (brand_data['цена_usd'].max() - brand_data['цена_usd'].min())
#Создание BCG-диаграммы
plt.figure(figsize=(9, 8))
plt.scatter(brand_data['количество'], brand_data['цена_usd'], s=700, alpha=0.8, edgecolors='k')
#Добавление квадрантов
plt.axvline(0.5, color='grey', linestyle='-')
plt.axhline(0.5, color='grey', linestyle='-')
#Подписи квадрантов
plt.text(0.25, 0.75, 'Вопросительные знаки', ha='center', va='center', fontsize=14, alpha=0.5)
plt.text(0.75, 0.75, 'Звезды', ha='center', va='center', fontsize=14, alpha=0.5)
plt.text(0.25, 0.25, 'Собаки', ha='center', va='center', fontsize=14, alpha=0.5)
plt.text(0.75, 0.25, 'Дойные коровы', ha='center', va='center', fontsize=14, alpha=0.5)
#Метки брендов
for i, brand in enumerate(brand_data['бренд']):
plt.annotate(brand, (brand_data['количество'].iloc[i], brand_data['цена_usd'].iloc[i]))
#Добавление сетки
plt.grid(True, linestyle='--', alpha=0.8)
plt.xlabel('Количество (Рыночная доля)')
plt.ylabel('Цена (Рыночный рост)')
plt.title('BCG-анализ Mercur Auto')
plt.show()
Вопросительные знаки - обычно это начальная точка новых товаров. Характерны такие признаки как высокий темп роста продаж, требуют больших инвестиций в поддержку и развитие, низкая прибыль в краткосрочном периоде.
Звезды - лидеры растущего рынка. Имеется высокий темп роста продаж, высокий уровень прибыли, возможен дальнейший рост, но требует значительных инвестиций.
Собаки - убыточный товар. Зачастую возможности по росту продаж ограничены, это может быть новый товар на рынке потерпевший неудачу, или же товар падающего рынка.
Дойные коровы - лидеры стагнирующего рынка. Имеют высокий уровень прибыли, дальнейший рост вряд-ли случится, эта категория питает компании долгосрочной стабильной прибылью.
Выведенный график BCG анализа Mercur Auto показывает что у компании имеются две марки авто (Ауди и Порше) являющихся яркими представителями вопросительных знаков, а так же Фольксвагены в роли дойных коров, являющиеся основой прибыли Mercur Auto.
Исходя из этого анализа выдвигаю следующие рекомендации:
Учитывая массовость и прибыльность Фольксвагенов, рекомендую выставить еще одну марку авто - Scoda. Она так же относится к концерну Фольксваген Гроуп, так же производится на широкую аудиторию и имеет доступную стоимость для большинства потребителей. Я полагаю что этот бренд займет нишу "звёзд" и в дальнейшем окажется "дойной коровой" повторив путь Фольксвагена, т.к. тоже имеет потенциал массово продаваться. Конечно же данное внедрение требует дополнительного тщательного анализа рынка для принятия решения.
Для развития премиум сегмента следует подготовить хорошую рекламную кампанию. Рекомендую организовать временные скидки, бонусы, подарки или финансовые программы для привлечения внимания покупателей. Обеспечить высокий уровень обслуживания клиентов в салоне и после продажи тем самым показав статус салонов с премиум сегментом авто. В дальнейшем, при благоприятном исходе событий рассмотреть на внедрение в продажу новых брендов премиум класса.
Следует всегда учитывать специфику люксовых авто. Продаж закономерно будет меньше относительно доступных автомобилей, но увеличив темп роста продаж инвестициями в развитие данного направления можно добиться ощутимого прироста в прибыли на долгосрочной перспективе.
Проведена комплексная очистка датасета и восстановление утраченных данных, с попыткой сохранить максимум имеющейся информации. Были удалены лишние столбцы дублирующие информацию, оставшиеся приведены к snake_case стилю для удобства работы с ними, числа приведены к нужным типам данных, неявные дубликаты заменены на корректные значения, восстановлены и сокращены (для оптимзации скорости загрузки датасета) типы привода к единому обозначению, сокращены (для опримизации скорости загрузки датасета) обозначения вида топлива, заполнены пропуски значений с задачей максимально сберечь данные в датасете.
Чаще всего приобретались легковые авто и внедорожники.
С большим отрывом лидируют такие бренды как Lada, Tayota, Hyundai. Это можно объяснить широкой доступностью расходников и запчастей на данные марки, привлекательной ценой (в этом плане выигрывает Лада у всех), а у Тайоты и Хёндая высочайший срок службы.
GAZ, KAMAZ, UAZ самые популярные авто для коммерции. GAZ пользуется спросом у спецслужб (скорая, полиция), Камазы распространены в строительных организациях и транспортных компаниях, Уазики гибки в использовании, их линейка коммерческого транспорта имеет как авто для перемещения пассажиров, так и грузовые авто до 3.5 тон.
Объем продаж к сентябрю 2019го составлял 1322 миллиона долларов, прирост был плавным на протяжении всего периода. Динамика продаж показывает нам тоже относительно плавную картину происходящего, в феврале мы имеем самый низкий показатель, а в июле всплеск продаж выделяющийся на общей картине. Ажиотаж к покупке Tayota Camry мог привести к повышенной активности продаж в июле.
Бипэк авто, крупнейший холдинг имеющий самую большую долю авторынка Казахстана (30,8%). Помимо нблюдаем дистрибьютора Tayota motor kazahstan (24,3% рынка) и astana motors (20,7%).
Лидеры продаж по регионам Алматы (13558 продаж) и Нур-Султан (9981 продаж). В средних значениях от 3157 до 3741 продаж держатся Костанай, Атырау, и Шымкент.
Общая выручка за весь период с января по сентябрь 2019го года у компании Mercur Auto составила 19 355 276 usd. Средняя ежемесячная выручка составляет 2 150 586 usd.
Фольксваген лидирует и в количестве проданных авто (84%, 546 штук), и в сумме продаж (10 182 272 usd) за весь период. Доля продаж по количеству Ауди и Порше всего по 8% каждый (по 52 автомобиля продано у каждого бренда).
Алматы превосходит по количеству продаж каждой марки авто все остальные регионы вместе взятые (484 единиц), в то время как остальные регионы не превышают 60 продаж за имеющийся период. В Алматы продано 390 Фольксвагенов, 51 Порш, и 43 Ауди.
Отказ от продаж Фольксагенов значительно нарушил рост прибыли для компании. Попытка оставить только премиум сегмент откзавшись от доступных авто для широкой аудитории потребителя повлекло за собой резкое падение продаж, реализация Фольксвагенов составляла львинную долю продаж в каждом из регионов без исключения.
Рекомендую ввести индексацию строк присваивая уникальный id для каждой. Это избавит массив данных от множества явных дубликатов, искать информацию станет легче.
Рекомендую заблокировать возможность ручного ввода информации о характеристиках автомобиля. Необходимо сделать выпадающее окно с вариантами выбора вида топлива, типа привода, коробки передач. Таким образом мы получим стандарт введения информации в базу данных, что позволит быстро ориентироваться в них и оперативно собирать статистику. Так же это облегчит жизнь аналитикам данных.
Рекомендую вести учет информации в единой БД. При объединении данных хранящихся на разных сервисах/облаках неизбежно возникают съехавшие значения, ошибки при выгрузке данных, а так же может быть утеряна часть этих данных. Это позволит иметь быстрый доступ к архивам без надобности склеивать данные, убережет их от возникновения части ошибок при выгрузке.
Рекомендую переименовать в БД поля латинскими символами. Это так же стандартизирует вид базы, упростив работу с данными аналитикам/инженерам данных.
Необходимо вернуть в продажу Фольксвагены. Эти машины пользуются спросом, отказ от них наносит удар по прибыли компании.
Рекомендую остатки Порше и Ауди перевезти в Алматы, и сконцентрироваться на продаже премиум сегмента именно там. С такими показателями продаж реализация премиум сегмента будет лучше.
Учитывая массовость и прибыльность Фольксвагенов, рекомендую выставить еще одну марку авто - Scoda. Она так же относится к концерну Фольксваген Гроуп, так же производится на широкую аудиторию и имеет доступную стоимость для большинства потребителей. Я полагаю что этот бренд займет нишу "звёзд" и в дальнейшем окажется "дойной коровой" повторив путь Фольксвагена, т.к. тоже имеет потенциал массово продаваться. Конечно же данное внедрение требует дополнительного тщательного анализа рынка для принятия решения.
Для развития премиум сегмента следует подготовить хорошую рекламную кампанию. Рекомендую организовать временные скидки, бонусы, подарки или финансовые программы для привлечения внимания покупателей. Обеспечить высокий уровень обслуживания клиентов в салоне и после продажи тем самым показав статус салонов с премиум сегментом авто. В дальнейшем, при благоприятном исходе событий рассмотреть на внедрение в продажу новых брендов премиум класса.
Следует всегда учитывать специфику люксовых авто. Продаж закономерно будет меньше относительно доступных автомобилей, но увеличив темп роста продаж инвестициями в развитие данного направления можно добиться ощутимого прироста в прибыли на долгосрочной перспективе.
В случае отказа от Фольксвагенов держать салоны во всех остальных регионах кроме Алматы не целесообразно. Рекомендую их закрыть, таким образом сократив расходы компании на аренду помещений.